CC_SHA256 为不同的输入生成相同的输出
CC_SHA256 generates same output for different input
这是一个基本的 CC_SHA256 示例:
-(void)hash:(NSData *)input
{
NSLog(@"Input is %@", [self NSDataToHex:input]);
NSMutableData *result = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
CC_SHA256(CFBridgingRetain(input), input.length, result.mutableBytes);
NSLog(@"RESULT is %@", result);
}
该算法似乎运行正常。小测试:
NSString* str = @"abcde";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
[self hash:data];
NSString* str2 = @"fghijk";
NSData* data2 = [str2 dataUsingEncoding:NSUTF8StringEncoding];
[self hash:data2];
给出以下输出:
Input is 6162636465
RESULT is <91681b5f 162cf494 238e5cac 0debbe92 c3ede9bf 4bcc7e79 845b774f b33e99f7>
Input is 666768696A6B
RESULT is <cccf7b6f 9acb96ae 84e9852b 1a753825 d6750555 57175c78 f86cf5fb bb3cfca7>
现在,如果我将第二个参数 (input.length) 更改为 3,我会得到以下输出:
Input is 6162636465
RESULT is <5e83c408 f722bb9a 9f602d85 c186bcb1 ebb8fa2f 0df2cc08 5eaf2522 92b01570>
Input is 666768696A6B
RESULT is <5e83c408 f722bb9a 9f602d85 c186bcb1 ebb8fa2f 0df2cc08 5eaf2522 92b01570>
这些哈希是相同的。我希望 CC_SHA256 算法只散列我输入的前 3 个字符,但显然,它不是那样工作的。此外,如果我重新启动模拟器,生成的哈希与第一次不同(但仍然彼此相等)。
为什么会发生这种行为?请不要为此问题提供(明显的)解决方法。我真的很想知道为什么算法会这样。
SHA(和任何哈希算法)应该是确定性的,因此它在不同版本之间的变化表明您可能使用不当。
我的猜测是,如果您只是传递输入的引用,那么您正在对与 NSData
相关的一些内部数据进行哈希处理,因此前几个字节相同,但不同的 lanches 不同。
查看这些其他问题之一 (Sha256 in Objective-C for iPhone) 以在 iOS 上正确实施 SHA-256。
(来自上面的答案):
-(NSString*)sha256HashFor:(NSString*)input
{
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
{
[ret appendFormat:@"%02x",result[i]];
}
return ret;
}
这是一个基本的 CC_SHA256 示例:
-(void)hash:(NSData *)input
{
NSLog(@"Input is %@", [self NSDataToHex:input]);
NSMutableData *result = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH];
CC_SHA256(CFBridgingRetain(input), input.length, result.mutableBytes);
NSLog(@"RESULT is %@", result);
}
该算法似乎运行正常。小测试:
NSString* str = @"abcde";
NSData* data = [str dataUsingEncoding:NSUTF8StringEncoding];
[self hash:data];
NSString* str2 = @"fghijk";
NSData* data2 = [str2 dataUsingEncoding:NSUTF8StringEncoding];
[self hash:data2];
给出以下输出:
Input is 6162636465
RESULT is <91681b5f 162cf494 238e5cac 0debbe92 c3ede9bf 4bcc7e79 845b774f b33e99f7>
Input is 666768696A6B
RESULT is <cccf7b6f 9acb96ae 84e9852b 1a753825 d6750555 57175c78 f86cf5fb bb3cfca7>
现在,如果我将第二个参数 (input.length) 更改为 3,我会得到以下输出:
Input is 6162636465
RESULT is <5e83c408 f722bb9a 9f602d85 c186bcb1 ebb8fa2f 0df2cc08 5eaf2522 92b01570>
Input is 666768696A6B
RESULT is <5e83c408 f722bb9a 9f602d85 c186bcb1 ebb8fa2f 0df2cc08 5eaf2522 92b01570>
这些哈希是相同的。我希望 CC_SHA256 算法只散列我输入的前 3 个字符,但显然,它不是那样工作的。此外,如果我重新启动模拟器,生成的哈希与第一次不同(但仍然彼此相等)。
为什么会发生这种行为?请不要为此问题提供(明显的)解决方法。我真的很想知道为什么算法会这样。
SHA(和任何哈希算法)应该是确定性的,因此它在不同版本之间的变化表明您可能使用不当。
我的猜测是,如果您只是传递输入的引用,那么您正在对与 NSData
相关的一些内部数据进行哈希处理,因此前几个字节相同,但不同的 lanches 不同。
查看这些其他问题之一 (Sha256 in Objective-C for iPhone) 以在 iOS 上正确实施 SHA-256。
(来自上面的答案):
-(NSString*)sha256HashFor:(NSString*)input
{
const char* str = [input UTF8String];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(str, strlen(str), result);
NSMutableString *ret = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH*2];
for(int i = 0; i<CC_SHA256_DIGEST_LENGTH; i++)
{
[ret appendFormat:@"%02x",result[i]];
}
return ret;
}