Я хотел бы подписать запрос с помощью HMAC SHA512, но я, кажется, испортил кодирование и декодирование из и в NSData и NSString. Я отчаянно пытался понять, что не так, но я просто не понимаю, что правильно.
ПСЕВДОКОД:
function hmac_512(msg, sec) {
sec = Base64Decode(sec);
result = hmac(msg, sec, sha512);
return Base64Encode(result);
}
secret = "7pgj8Dm6";
message = "Test\0Message";
result = hmac_512(message, secret);
if (result == "69H45OZkKcmR9LOszbajUUPGkGT8IqasGPAWqW/1stGC2Mex2qhIB6aDbuoy7eGfMsaZiU8Y0lO3mQxlsWNPrw==")
print("Success!");
else
printf("Error: %s", result);
Моя реализация:
+(void)doSomeMagic{
NSString *message = @"Test\0Message";
NSString *signedRequest = [self signRequestForParameterString:message];
//checking against CORRECT (from JAVA equivalent) signed request
if ([signedRequest isEqualToString:@"69H45OZkKcmR9LOszbajUUPGkGT8IqasGPAWqW/1stGC2Mex2qhIB6aDbuoy7eGfMsaZiU8Y0lO3mQxlsWNPrw==" ])
NSLog(@"Success!");
else
NSLog(@"Error!");
}
Вот метод подписи:
+(NSString *)signRequestForParameterString:(NSString*)paramStr{
NSString *secret = @"7pgj8Dm6";
// secret is base64 encoded, so I decode it
NSData *decodedSecret = [secret base64DecodedData];
NSString *decodedSecretString = [NSString stringWithUTF8String:[decodedSecret bytes]];
NSData *data = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *dataString = [NSString stringWithUTF8String:[data bytes]];
return [self generateHMACSHA512Hash:decodedSecretString data:dataString];
}
Вот функция хеширования:
+(NSString *)generateHMACSHA512Hash:(NSString *)key data:(NSString *)data{
const char *cKey = [key cStringUsingEncoding:NSASCIIStringEncoding];
const char *cData = [data cStringUsingEncoding:NSASCIIStringEncoding];
unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA512, cKey, strlen(cKey), cData, strlen(cData), cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC
length:sizeof(cHMAC)];
NSString *hash = [HMAC base64EncodedString];
return hash;
}
Я почти уверен, что это связано с кодировкой строк (decodedSecretString и dataString). decodedSecretString
(декодированный base64) после декодирования кодируется в ASCII. Однако, когда я вызываю метод хеширования, я снова кодирую его в ascii, что приводит к нулевой ошибке. Меня все сейчас смущает.
+signRequestForParameterString:
, когда он будет просто возвращен в массив байтов в методе HMAC? В чем смысл этого? Просто передайте строку методу HMAC. И вам, вероятно, следует придерживаться UTF8, а не ASCII, если только вы не знаете, что у вас есть текст ASCII, а сервер не может понять UTF-8. - person John Cromartie   schedule 29.11.2013