【发布时间】:2013-11-29 16:27:13
【问题描述】:
我想用 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,这将导致 null 错误。现在一切都让我感到困惑。
【问题讨论】:
-
有很多代码需要查看。你不能稍微调试一下,然后找出问题所在吗?
-
如果您的密钥是 Base64 编码的,那么您应该对其进行解码并将解码后的 NSData 传递给您的 HMAC 函数。不要把它变回字符串。
-
为什么要在
+signRequestForParameterString:中从一个NSString 到NSData 再返回到NSString,而它只是在HMAC 方法中转回一个字节数组?那有什么意义呢?只需将字符串传递给 HMAC 方法。而且您可能应该坚持使用 UTF8,而不是 ASCII,除非您知道您有 ASCII 文本并且服务器无法理解 UTF-8。
标签: objective-c macos sha hmac nsstringencoding