Необходимо создать хэш HMAC SHA256 в Objective C, как в Java
Мне нужно создать хеш с использованием HMAC SHA256. Я использую следующий код в Java. Мне нужен эквивалентный код в Objective-C.
javax.crypto.Mac mac = javax.crypto.Mac.getInstance(type);
javax.crypto.spec.SecretKeySpec secret = new javax.crypto.spec.SecretKeySpec(key.getBytes(), type);
mac.init(secret);
byte[] digest = mac.doFinal(value.getBytes());
StringBuilder sb = new StringBuilder(digest.length * 2);
String s="";
for (byte b: digest) {
s = Integer.toHexString(b);
if (s.length() == 1) {
sb.append('0');
}
sb.append(s);
}
return sb.toString();
Ключ = YARJSuwP5Oo6/r47LczzWjUx/T8ioAJpUK2YfdI/ZshlTUP8q4ujEVjC0seEUAAtS6YEE1Veghz+IDbNQb+2KQ==
Значение =
id=456|time=19:10|nonce=8
Выход =
4effffffd8ffffffce7cffffffc4ffffffc71b2f72ffffffdc21ffffffa1ffffffe0ffffffe62d32550b0771296bffffff9c1159ffffffdeffffff8675ffffff9928654c
У меня есть эта функция Objective-C:
//Hash method Definition
- (NSString *)getHashEncription:(NSString *)key andData:(NSString *)data{
NSLog(@"Secret Key %@ And Data %@", key, data);
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
//HmacSHA256
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
length:sizeof(cHMAC)];
[Base64 initialize];
NSString *b64EncStr = [Base64 encode:HMAC];
NSLog(@"Base 64 encoded = %@",b64EncStr);
NSLog(@"NSData Value %@", HMAC);
// unsigned char hashedChars[32];
// NSString *inputString;
// inputString = [NSString stringWithFormat:@"hello"];
// NSData * inputData = [inputString dataUsingEncoding:NSUTF8StringEncoding];
// CC_SHA256(inputData.bytes, inputData.length, hashedChars);
return [[NSString alloc] initWithData:HMAC encoding:NSASCIIStringEncoding];
}//End of getHashEncription
Результат, который я получаю, следующий:
8736bc4aa7fc3aa071f2b4262b6972a89d2861559a20afa765e46ff17cb181a9
Я попытался удалить кодировку base64, но это не сработало.
Любые предложения приветствуются.
Ответы
Ответ 1
Вам нужно исправить свой hmac-принтер Java, потому что 4effffffd8ffffffce7cffffffc4ffffffc71b2f72ffffffdc21ffffffa1ffffffe0ffffffe62d32550b0771296bffffff9c1159ffffffdeffffff8675ffffff9928654c
недействителен. Все те ffffff
содержат бесплатную подписку на байты до 32-разрядных целых чисел, прежде чем преобразовать их в шестнадцатеричный. Предположительно, правильный hmac 4ed8ce7cc4c71b2f72dc21a1e0e62d32550b0771296b9c1159de86759928654c
.
В любом случае, я подозреваю, что вы неправильно вызываете свой метод. Я скопировал ваш код в тестовую программу, которая дает мне этот вывод для вашего ключа и данных:
2011-12-10 13:03:38.231 hmactest[8251:707] test hmac = <4ed8ce7c c4c71b2f 72dc21a1 e0e62d32 550b0771 296b9c11 59de8675 9928654c>
Это соответствует вашему желаемому результату (за исключением ошибок расширения знака).
Здесь моя тестовая программа:
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonHMAC.h>
NSData *hmacForKeyAndData(NSString *key, NSString *data)
{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
return [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
}
int main (int argc, const char * argv[])
{
@autoreleasepool {
// Compare to http://en.wikipedia.org/wiki/HMAC#Examples_of_HMAC_.28MD5.2C_SHA1.2C_SHA256_.29
NSLog(@"empty hmac = %@", hmacForKeyAndData(@"", @""));
NSLog(@"test hmac = %@", hmacForKeyAndData(@"YARJSuwP5Oo6/r47LczzWjUx/T8ioAJpUK2YfdI/ZshlTUP8q4ujEVjC0seEUAAtS6YEE1Veghz+IDbNQb+2KQ==", @"id=456|time=19:10|nonce=8"));
}
return 0;
}
Ответ 2
Линия
CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
имеет ошибку
Если в вашем ключе будет 0x00 байт strlen(cKey)
будет давать неправильную длину, и процесс генерации hmac вызовет некоторый мусор.
В моей реализации я изменил это на:
CCHmac(kCCHmacAlgSHA256, cKey, [key length], cData, [data length], cHMAC);