【问题标题】:CC_SHA256 generates same output for different inputCC_SHA256 为不同的输入生成相同的输出
【发布时间】:2016-04-14 22:53:32
【问题描述】:

这是一个基本的 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 个字符进行散列,但显然,它不是那样工作的。此外,如果我重新启动模拟器,生成的哈希值与第一次不同(但仍然彼此相等)。

为什么会发生这种行为?请不要为这个问题提供(明显的)解决方法。我真的很想知道为什么算法会这样。

【问题讨论】:

  • 我认为您没有为哈希传递正确的参数。尝试传入input.bytes 而不是CFBridgingRetain(input)。我的猜测是,如果您只是传入 input 的引用,那么您正在散列一些与 NSData 相关的内部数据,因此前几个字节在 lanches 之间是相同的和不同的。 SHA 应该是确定性的,因此对于相同的输入它正在改变这一事实意味着您使用它不正确。
  • 你似乎是对的。我还认为随机性很奇怪。您可以添加您的答案,以便我将其标记为正确吗?
  • 不幸的是,在实际应用程序中,输入字符串要长得多(64 个字符),输入大小设置为 32。两个(完全不同的)字符串仍然给出相同的哈希值...

标签: objective-c sha256


【解决方案1】:

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;
}

【讨论】:

  • 感谢您的回答。然而奇怪的是,对于一个大字符串,即使对象的前 32 个字节似乎也是相同的,因为两个长度为 64 的不同字符串都给出相同的哈希
猜你喜欢
  • 2014-11-08
  • 2012-01-18
  • 2018-07-13
  • 1970-01-01
  • 1970-01-01
  • 2013-08-06
  • 2021-09-09
  • 1970-01-01
  • 2012-09-08
相关资源
最近更新 更多