2009-05-27 113 views
3

我正在开发一个.NET 3.5项目,我需要一个32位散列值。 .NET密码学类中似乎没有任何方法返回32位散列(MD5是128位,SHA1是160位等)。我实现了一个CRC32类,但是我发现已经存在的SHA1和MD5哈希函数要快得多。160位SHA1哈希的前32位是CRC32哈希的可接受替代吗?

使用SHA1散列函数会不会有任何问题(即增加冲突的可能性),并将前32位存储为我的散列值?

+2

你在做什么,你不能存储整个20个字符的SHA-1哈希?另外,CRC32不是一个散列,它是一个传输错误检测机制,所以如果你需要错误检测,散列并不是真正的方法。 – jmucchiello 2009-05-27 13:54:30

+0

为节省空间,选择了4字节散列。哈希将用于校验来自监控设备的数据块,并且可能会有数十万个数据块。我们会看到,也许存储整个事情不会是一个问题。 你说了一些有趣的东西。 “传输错误检测机制”和哈希之间的区别究竟是什么?密码强度(这个特定的应用程序不需要)? – raven 2009-05-27 14:01:00

+0

无耻的自我插件:cmdhashgen支持CRC32并且源自HashAlgorithm,所以它可以像其他人一样使用,请检查Crc32.cs:http://cmdtools.codeplex.com/ – 2009-05-27 14:16:50

回答

6

除非你想CRC32的额外功能(线性代码),你应该罚款将输出切割为32位。

无论切割的一些加密散列函数的输出会伤害其安全相对于抗碰撞是一个开放的研究问题(如果我记错存在“非自然”构造的例子)。但NIST(可能经过NSA的批准)无论如何都使用切割技术从SHA-256获取SHA-224(请参阅article about SHA in wikipedia)。

编辑:CRC32允许检测(也许是正确的)单比特错误,而加密哈希函数应该有属性,你不能找到两个具有相同散列值的输入。

您是否知道“生日悖论”(请参阅​​wikipedia)?随着32位校验你希望得到的碰撞(即,相同的哈希值的两个输入)如果您有关于2^16个输入,并且要凑更多的投入。 (重读您的评论,这可能不是你的问题。)

0

如果你不打算将32位用于加密目的,那么你应该没问题。否则,我不会依赖于与整个散列具有相同分布的第一个32位。

为什么你不能只使用更广泛的可用哈希?

0

CRC32可能适合您的需求。这已在this question中讨论过。

在截断哈希基元方面,唯一大量使用的应用是用于生成密钥的SSL/TLS Pseudo Random Function (PRF)。它使用HMAC的种子和标签通过多次散列生成尽可能多的字节,然后截断所需的字节数量。

至于您的具体问题,虽然,你可以阅读哈希的输出入的Int32的,然后异或它们放在一起,如果你是偏执狂:

static void Main() 
{ 
    int xorCrc = GetHashedCrc(new SHA1Cng(), new byte[] {0xDE, 0xAD, 0xBE, 0xEF}); 
} 

private static int GetHashedCrc(HashAlgorithm algorithm, byte[] bytesToHash) 
{ 
    byte[] hash = algorithm.ComputeHash(bytesToHash); 
    int totalInt32s = hash.Length/sizeof(int); 
    int result = 0; 
    for(int i = 0; i < totalInt32s; i++) 
    { 
     int currentInt = BitConverter.ToInt32(hash, sizeof(int)*i); 
     result = result^currentInt; 
    } 

    return result; 
} 
2

鉴于散列函数平均分配其输入假设在它的共域中,假设它也将平均分配给它的任何子集似乎是合乎逻辑的。 但是,使用“本机”32位散列函数可能仍然是更好的选择。也许更多的人可以为我们提供一个比我的直觉更好的理由:)

1

你为什么不只是使用string.GetHashCode()。它旨在计算32位散列值,并在给定实际数据的情况下产生很少的冲突。当然,这并不安全,但你的问题并不包括这个要求。