我想知道是否曾经一起使用不同的哈希值(例如md5(sha1($data)))来确保数据安全,以及是否有任何理由(正面或负面答案)。
不同的哈希算法曾经一起使用过吗?
一起使用两个散列函数,作为防止违反其中一个函数的额外安全措施,是很微妙的。连接(数据使用两个哈希函数进行哈希处理,结果被连接)产生的抗碰撞性至少相当于两个函数中最强的(令人惊讶的是,并没有比这更好);另一方面,串联使得抗原像性并不比这两个函数中最弱的一个好。作品(数据用一个函数散列,结果用另一个函数散列)提供相反的结果:原像抗性至少与两个函数中最强的一样好(取决于一些定义的细微之处,取决于你是否想要抗性反对恢复使用的数据,或者只是产生相同输出的任何消息),但对于碰撞,最弱的函数定义了整体阻力。
因此,将两个散列函数组合在一起充其量是喜忧参半。SSL/TLS,直到 TLS 1.1,将 MD5 和 SHA-1 结合到其内部“PRF”中,特别是用作密钥派生功能(将协商的秘密扩展为对称加密和完整性控制的密钥);这两个函数都在HMAC中使用,然后转换为自定义 PRNG,并将两个生成的流一起异或。目的是拥有一个密钥推导函数,它可以抵抗 MD5 或 SHA-1 的密码分析破解(这是否真的有效还没有被正式证明;它真的取决于“破解”的性质)。有趣的是,TLS 1.2恢复为使用单个(可配置的)散列函数。将两个哈希函数组合在一起意味着您必须同时实现这两个函数,这对于通常对代码大小有严格限制的嵌入式系统来说是一个问题。
所以通常的建议是:不要这样做。很难做到正确,即使你没有引入任何弱点,也不清楚你是否真的以这种方式获得了任何东西,安全方面。另一方面,运营成本明显。使用单个更好的散列函数(这意味着:抛弃 MD5 和 SHA-1,只使用 SHA-256)似乎更好,并且具有算法敏捷性(使散列函数可配置,以便您以后可以更改它)。
看看Crypto.SE 上的这个问题。这种结构有一些微妙之处。例如,在您的示例中,sha1(最里面的哈希函数)的冲突会立即产生整个事物的冲突。
令人惊讶的是,哈希的串联仅是安全的,因为当涉及到原像攻击时,您使用的哈希是最弱的(即,给定 x=hash(m),找到 m' 使得 hash(m')==x,其中 m ' 可以等于 m)。然而,对于碰撞,它相当强大。
附带说明一下,MD5 和 SHA1 很弱,不应该在新系统中使用。