[英]NSString from NSData always null
我想用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;
}
我很确定这是由于字符串的编码(decodingSecretString和dataString)。 解码后的decodedSecretString
(解码后的base64)以ASCII编码。 但是,当我调用哈希方法时,我再次在ascii中对其进行编码,这将导致空错误。 现在一切都让我很困惑。
您的秘密不会解码为有效的UTF-8字符串,并且Java允许字符串中的NUL字节,但是当您将“Test \\ 0Message”转换为C字符串并使用strlen时,其长度为4。
这样的事情应该有效:
+(NSString *)signRequestForParameterString:(NSString*)paramStr{
NSString *secret = @"7pgj8Dm6";
NSData *data = [paramStr dataUsingEncoding:NSUTF8StringEncoding];
return [self generateHMACSHA512Hash:[secret base64DecodedData] data:data];
}
+(NSString *)generateHMACSHA512Hash:(NSData *)key data:(NSData *)data{
unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA512, key.bytes, key.length, data.bytes, data.length, cHMAC);
NSData *HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];
return [HMAC base64EncodedString];
}
在进行HMAC或其他加密函数时,您应该构建一些不首先处理字符串的基本方法/函数。 然后,您可以创建以方便的方式解码/编码字符串数据或摘要的包装器方法。
+ (NSData *)dataBySigningData:(NSData *)data withKey:(NSData *)key
{
unsigned char cHMAC[CC_SHA512_DIGEST_LENGTH];
CCHmac(kCCHmacAlgSHA512, [key bytes], [key length], [data bytes], [data lenght], cHMAC);
return [[NSData alloc] initWithBytes:cHMAC length:CC_SHA512_DIGEST_LENGTH];
}
+ (NSData *)dataBySigningMessage:(NSString *)message withKey:(NSData *)key
{
return [self dataBySigningData:[message dataUsingEncoding:NSUTF8StringEncoding]
withKey:[key dataUsingEncoding:NSUTF8StringEncoding]];
}
(注意:此代码未经过测试,只是在文本编辑器中被黑客攻击)
不要担心密钥或数据的字符串表示。 然后你可以从那里去,例如获取摘要的base64编码。
加密函数不关心字符串或文本编码。 他们关心字节。 字符串(在C中,因为它们是以空值终止的)仅仅是可以在数据中表示的子集。 因此处理字符串会受到严重限制。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.