iOS/Objective C:SHA-1和Base64

ton*_*air 2 iphone hash base64 sha1 objective-c

我必须将短语'1234'转换为其SHA-1哈希的Base64编码.

我希望:'1234'= cRDtpNCeBiql5KOQsKVyrA0sAiA =(此示例与服务器通信有关)...

但是当我在这些网站上检查手动或在我的XCode项目中使用我的方法时,结果总是不同的:

1234

SHA-1(后http://www.sha1.cz/)7110eda4d09e062aa5e4a390b0a572ac0d2c0220

在Base64之后(http://base64-encoder-online.waraxe.us/)NzExMGVkYTRkMDllMDYyYWE1ZTRhMzkwYjBhNTcyYWMwZDJjMDIyMA ==

这是我的SHA-1功能:

- (NSString *)sha1:(NSString *)str {
    const char *cStr = [str UTF8String];
    unsigned char result[CC_SHA1_DIGEST_LENGTH];
    CC_SHA1(cStr, strlen(cStr), result);
    NSString *s = [NSString  stringWithFormat:
                   @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
                   result[0], result[1], result[2], result[3], result[4],
                   result[5], result[6], result[7],
                   result[8], result[9], result[10], result[11], result[12],
                   result[13], result[14], result[15],
                   result[16], result[17], result[18], result[19]
                   ];

    return [s lowercaseString];
}
Run Code Online (Sandbox Code Playgroud)

对于Base64,我使用这个类:http://cocoawithlove.com/2009/06/base64-encoding-options-on-mac-and.html

这是SHA-1和Base64的调用:

 NSString *pwHash =[self sha1:self._txtFieldPW.text]; //In my case '1234'
 NSLog(@"Hash: %@",pwHash); //7110eda4d09e062aa5e4a390b0a572ac0d2c0220
 //7110eda4d09e062aa5e4a390b0a572ac0d2c0220
 NSData *pwHashData = [[NSData alloc]initWithData:[pwHash dataUsingEncoding:1]];
 NSString *base64 = [pwHashData base64Encoding];
 NSLog(@"Base64: %@",base64); 
 //NzExMGVkYTRkMDllMDYyYWE1ZTRhMzkwYjBhNTcyYWMwZDJjMDIyMA==
Run Code Online (Sandbox Code Playgroud)

出了什么问题?

Sev*_*yev 9

哈希是二进制值."cRDtpNCeBiql5KOQsKVyrA0sAiA ="字符串是编码的散列的二进制值的结果.同时,"NzExMGVkYTRkMDllMDYyYWE1ZTRhMzkwYjBhNTcyYWMwZDJjMDIyMA =="字符串是对哈希的十六进制表示的Base64变换的结果.

这有意义吗?所以你有一个SHA1哈希,一个20字节的数组:{0x71,0x10,...}.您可以按原样对该块内存进行Base64编码.或者您可以将每个字节转换为两个小写的十六进制数字,然后您将获得ASCII字符串"7110eda4d09e062aa5e4a390b0a572ac0d2c0220".如果将Base64编码应用于该字符串,而不是原始哈希字节,则将获得Base64值"NzExMGV ...".

编辑,具有额外的二元优点:重新制定第二个片段:

unsigned char result[CC_SHA1_DIGEST_LENGTH]; 
const char *cStr = [self._txtFieldPW.text UTF8String];
CC_SHA1(cStr, strlen(cStr), result); //Now result contains the hash

//Wrap the result in a NSData object
NSData *pwHashData = [[NSData alloc] initWithBytes:result length: sizeof result];  
//And take Base64 of that
NSString *base64 = [pwHashData base64Encoding];  
NSLog(@"Base64: %@",base64); 
Run Code Online (Sandbox Code Playgroud)

并摆脱该sha1方法.一旦你移除了怪异的stringWithFormat电话,它就是一个双线.如果你真的想在日志中使用hex哈希,那就是我的客人; 但是不要将十六进制字符串视为哈希的真值,因为它不是.

除非您使用ARC,否则不要忘记NSData随后释放该对象.