我在Objective-C中使用REST API,需要根据此规范(https://web-payments.org/specs/source/http-signatures/)对每个HTTP请求进行签名 .
这一切看起来都很简单,但我在Objective-C VS和其中一些在线sha生成器(http://www.freeformatter.com/hmac-generator.html,http://hash.online-convert.com/sha256-generator)中获得了不同的结果 .
我把一些沙盒测试代码放在一起,以便在我的项目之外找到它 .
这是我的测试代码:
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCrypto.h>
NSString * hmacSHA256(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);
NSMutableString *result = [NSMutableString string];
for(int i = 0; i < sizeof cHMAC; i++) {
[result appendFormat:@"%02x", cHMAC[i]];
}
return result;
}
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSMutableString * data = [NSMutableString string];
[data appendString:@"(request-line) get /\n"];
[data appendString:@"date: Wed, 02 Jul 2014 22:12:37 GMT"];
NSString * key = @"5a30f5477e2fdea27c5bdef8d5b0b13bfc8c2c77c608169da637a58ac0bff23895b58f8de5ef982a";
NSLog(@"%@",data);
NSString * signature = hmacSHA256(key,data);
NSLog(@"signature: %@",signature);
}
return 0;
}
当我运行此测试代码时,我将其作为签名:
8315081c226a7b0a77093cf12ec6ce4e112fedff12ddfcfd752c909b58a9ae5e
但是当我粘贴这些行时:
(request-line) get /
date: Wed, 02 Jul 2014 22:12:37 GMT
对于其中一个在线生成器(http://www.freeformatter.com/hmac-generator.html,http://hash.online-convert.com/sha256-generator),这两个生成器都给我相同的签名:
71b09a1d0b8cde88f2b0c5bb78a06c4539994435e5e47700aa56d2194b9c2f08
那么我应该如何将上面的“unsigned char cHMAC”变量转换为正确的字符串呢?
谢谢 .
1 回答
您的问题是文本中的行结尾 . 实际上,您的程序正在生成正确的哈希值,但是您在Web工具中输入了不同的字符串,这就是您为程序提供文本的原因:
以下是您为Web工具提供的内容(假设您在Windows上执行此操作,并根据我的测试进行检查):
注意'\ r \ n' . 默认情况下,Windows(以及很可能是所有Web浏览器)使用回车符和换行符作为EOL序列 . Unix / Linux仅使用换行符,而Mac仅使用回车符 .
如果要检查任何其他哈希,请在程序中添加“\ r”进行测试,或使用记事本等程序控制行结尾创建文件,然后将其上传到列出的第二个站点 .