【发布时间】:2014-07-03 07:52:33
【问题描述】:
我在 Objective-C 中使用 REST API,需要根据此规范 (https://web-payments.org/specs/source/http-signatures/) 对每个 HTTP 请求进行签名。
这一切看起来都很简单,但我很难获得正确的“签名”值应该是什么。我在 Objective-C 与其中一些在线 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”变量转换为正确的字符串?
谢谢。
【问题讨论】:
-
不确定这是否是实际问题,但密钥不应该是实际密钥的十六进制表示,而不是 ASCII 表示吗? IE。您需要将十六进制解码为字节吗?
-
另外,我很确定“(请求行)”并不是按字面意思包含的,它只是意味着您应该包含请求行本身。
-
我的问题没关系。重要的是 objc 和在线生成器之间的区别。为什么我没有得到相同的签名。每个输入都相同,为什么结果不同..
标签: objective-c rest hmac sha256