2

我必须将一个人的姓氏、名字和出生日期的组合保存为哈希。此哈希稍后用于搜索具有完全相同属性的同一个人。我的问题是,如果 SHA-1 是一个有意义的算法。

据我了解 SHA-1,两个不同的人(具有不同属性)几乎不可能获得相同的哈希值。这是正确的吗?

4

3 回答 3

1

如果您想搜索一个知道这些凭据的人,您可以将 SHA-1 存储在数据库中(或 MD5 以提高速度,除非您有数亿人需要采样)。

散列将毫无价值,因为它不存储有关此人的信息,但它可以用于搜索数据库。您只想确保这三条信息匹配,因此将它们连接起来是安全的:

user.hash = SHA1(user.firstName + user.DOB + user.lastName)

当您查询时,您可以检查两者是否匹配:

hash = SHA1(query.firstName + query.DOB + query.lastName)

for user in database:
  if user.hash == hash:
    return user

我放在query.DOB中间是因为名字和姓氏可能会发生冲突,就像JohnDoe Bob出生在同一天一样John DoeBob。我不知道数字名称,所以我认为这将阻止像这样的碰撞;)

但如果这是一个大数据库,我会尝试 MD5。它更快,但有可能发生碰撞(在你的情况下,我可以保证不会发生碰撞)。但是,发生碰撞的可能性非常小。

从这个角度来看,碰撞是一种1 / 2^128事件,即:

                          1
---------------------------------------------------
340,282,366,920,938,463,463,374,607,431,768,211,456

这比:

0.0000000000000000000000000000000000000293873 %

确定你不会发生碰撞;)

于 2011-04-13T20:52:02.140 回答
1

哈希冲突是不可避免的。无论发生碰撞的机会多么小,如果您真的想要 100% 的识别,您不应该只依赖哈希。

如果使用散列来加速数据库搜索,则无需使用 SHA256。使用系统具有最小大小的任何散列函数(MySQL 的 MD5() 或者如果您的数据库不是那么大,您甚至可以尝试 CRC32)。就在您查询表时,您需要提供您正在搜索的所有条件:

SELECT * from user WHERE hash="AABBCCDD" AND firstname="Pavel" AND surname="Sokolov"

数据库维护一个值,称为索引基数。它是给定索引上数据唯一性的度量。因此,您可以将所需的字段与哈希字段一起索引,并且数据库将为查询自己选择最具选择性的索引。添加附加条件不会对性能产生负面影响,因为大多数数据库在从表中选择数据时只能使用一个索引,并且它们会选择具有最大基数值的那个。

数据库将需要首先选择与索引匹配的所有行,然后扫描它们以丢弃与其他条件不匹配的行。

如果你不能使用我描述的方法,那么,我认为即使是 MD5 碰撞概率也很低,在人名数据库上发生。

PS我希望你知道,你知道“一个人的姓氏,名字和出生日期的组合”不足以100%识别一个人吗?并且这种组合将比一些哈希冲突更快地匹配。

于 2011-04-13T21:04:21.650 回答
0

如果您担心碰撞,这里有一个很好的讨论:

了解 sha-1 碰撞弱点

如果您有安全问题,我会考虑使用 SHA-256。

于 2011-04-13T20:57:26.817 回答