很多文件将存储在数据库中,我需要文件哈希来唯一标识文件未被更改.(一般情况下,将用作Windows个人防火墙部分)
如果我理解"用作Windows个人防火墙"部分,MD5不是一个很好的算法选择.
MD5算法存在成功的攻击,它允许您找到一个不同的消息,该消息产生相同的散列而且工作量相对较少(与暴力相比).这种攻击过去没有真正的影响,例如当MD5用于哈希密码等时.与此同时,新的攻击已经被发现,所以MD5和SHA-1进行散列/在可怕的速度相撞,并与这些"老人"破解"正确咸"和单散列用户密码的整个数据库的哈希值不只是完全可行但已经证明了.
但是,在"确保此文件未被篡改"的特定应用中,这种攻击一直是一个问题,而不仅仅是最近.MD5会相当安全检测的位错误或修改的意外,但恶意软件试图绕过您的个人filewall,可以相当琐碎这么哈希符合原件的发现被感染二进制碰撞规避整个的安全性.
在这种情况下你应该使用SHA-256 [ 更新:同时,SHA-3已经出局,而我个人不同意NIST选择的胜利者(或者排除一些非常好的第2轮的模糊标准)候选人),使用SHA-3(Keccak)或SHA-3决赛选手之一是一个更安全的选择.所有的决赛选手都经过了经验丰富的团队的精心设计,经过了非常彻底的分析,到目前为止还没有一个真实的攻击或已知的问题,可以想象会导致真实的攻击,而且他们都有"更多位"(这本身并不意味着什么,但更多的位不伤害)].
此外,记住除了哈希之外总是保存文件的长度,这甚至会以可忽略的成本硬化甚至是糟糕的哈希.如果可以的话,计算两个不同的哈希值.这是很多攻击者更容易找到一些消息产生冲突的一个哈希比找到产生碰撞的消息,并且具有正是撞上两个不同的哈希值,并且具有相同的长度相同的长度,甚至留言.
由于带宽(磁盘和内存)在计算散列时是一个不可忽略的因素,因此甚至可能以相当的速度同时计算单个散列或两个散列.
我在计算CRC并用块密码加密相同的块之后观察到了这种效果.无论CRC是否计算在整体运行时间上的差异小于1%,因此它基本上是免费操作.
如果您认为自己有充分的理由不使用众所周知的标准哈希(性能约束?),那么您可以构建自己的安全哈希.使用Merkle-Damgård构造(或最近的HAIFA),您可以将任何安全块密码转换为安全散列函数.例如,使用固定密钥用AES加密每个输入块,然后在加密那个输出块之前将输出加到下一个块.最后一个块之后的输出是您的哈希值.
虽然"构建自己的"通常不是一个好主意,但在这种情况下确实可能有正当理由,因为AES在最新的处理器中很快并且在硬件中受支持.在我的机器上,AES以大约130MB/s的速度运行.在i7(具有硬件支持)上,它在互联网上报告大约570MB/s.
至于I/O有限,放松是正确的,磁盘很可能是限制因素,尽管它不需要.内存映射是你的朋友,特别是在你的特定情况下.
如果您检查在防火墙上申请权限的文件,那么这些文件将是已经加载到RAM中的可执行文件(它们可能会有什么不同,它们最终会被执行!).因此,映射已经在RAM中的页面将仅添加页表条目,或多或少是无操作.即使数据不在RAM中,内存映射的性能(和易用性)也是完全令人惊叹的,如果速度有任何问题,我现在很少使用其他任何东西.