一个关于 CommonCrypto 的问题

2012-02-23 05:00:22 +08:00
 Livid
同样的输入条件,同样的加密算法,理论上来说,应该可以产生完全一致的输出,但是 Objective-C 的输出始终是错的。

Python 代码:

payload['sig'] = base64.b64encode(hmac.new(bf3api_key, payload['data'], hashlib.sha256).digest(), '-_')

Objective-C 代码:

dataString = [[[[[data JSONRepresentation] dataUsingEncoding:NSUTF8StringEncoding] base64Encoding] stringByReplacingOccurrencesOfString:@"+" withString:@"-"] stringByReplacingOccurrencesOfString:@"/" withString:@"_"];
NSMutableDictionary * payload = [[NSMutableDictionary alloc] initWithCapacity:2];
[payload setObject:dataString forKey:@"data"];

const char * cKey = [BF3API_KEY cStringUsingEncoding:NSASCIIStringEncoding];
const char * cData = [dataString cStringUsingEncoding:NSASCIIStringEncoding];

unsigned char cHMAC[CC_SHA256_DIGEST_LENGTH];

CCHmac(kCCHmacAlgSHA256, cKey, strlen(cKey), cData, strlen(cData), cHMAC);

NSData * HMAC = [[NSData alloc] initWithBytes:cHMAC length:sizeof(cHMAC)];

NSString * hash = [HMAC base64Encoding];
hash = [hash stringByReplacingOccurrencesOfString:@"+" withString:@"-"];
hash = [hash stringByReplacingOccurrencesOfString:@"/" withString:@"_"];

[payload setObject:hash forKey:@"sig"];

输入是 data 和 key,目的是输出 sig。这些条件在两个版本的代码里是一样,用的也是同样的加密算法 SHA256,但是 Objective-C 出来就是错的。

因为最后 sig 会作为 post 参数提交到服务上进行验证,而 Python 生成的 sig 是可以过的,也就是正确的。但是 Objective-C 用 CommonCrypto 生成的 sig 就没法过了。

实在不明白为什么,所以请教这里的众多高手了。谢谢。
3749 次点击
所在节点    iDev
5 条回复
Livid
2012-02-23 05:50:20 +08:00
问题解决了。

CommonCrypto 生成的输出肯定是和其他语言的一样的。

确实是因为我输入的值在各种编码过程中造成的问题。
Livid
2012-02-23 05:52:22 +08:00
不过真的还是想借此机会吐槽一下 Objective-C,一件本来很简单的事情,用 Python 一句话可以解决,但是到了这边就各种周折。

另外就是,大家推荐一个比较好的将 NSDictionary 转化为 HTTP POST BODY 的 NSData 的开源实现吧?
Kai
2012-02-23 06:02:58 +08:00
RKRequestSerialization ?
shinyzhu
2012-02-23 08:54:35 +08:00
@Livid NSDictionary转换成POST body的在AFNetworking里面都有喔。具体代码在AFHTTPClient.m里面。

函数
NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding encoding);
把字典做成HTTP Body的格式,然后再用
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding;
转换成NSData,就可以直接放到body里面了。
tokki
2012-02-23 09:46:03 +08:00
这个asi里面也有的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/27947

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX