http://news.ycombinator.com/item?id=910203
我现在正在尝试证明和理解下面列出的哈希值为什么不安全,程序员不应该使用。H(k || m) --> SHA1("secret-key" + "name=bob,withdraw=$200")
H(m || k) --> SHA1("name=bob,withdraw=$200" + "secret-key")
根据文章所述,第一个例子完全失败了。SHA1(以及MD5和许多其他哈希)是共享称为Merkle-Damgaard的常见设计的机器,这意味着它们以块长度的块处理消息,并使用这些块来排列内部状态。输出SHA1是该状态的“最终”内容。但实际上没有任何东西可以“完成”SHA1状态;如果您在电线上看到SHA1值,则可以继续使用附加数据驱动Merkle-Damgaard机器。 这意味着您可以生成新消息,并将任意数据添加到末尾,这些消息看起来是真实的。此攻击非常容易实施;需要大约20行Ruby代码。
第二个例子也是有问题的,这也是本博客文章的主题。如果你在消息后面添加密钥,你就不能继续使用数据驱动哈希,因为一个无法猜测的秘密位于其末尾。我已经用C#编写了一个简单的哈希函数,试图证明作者的说法,但不管我在消息前后添加/填充什么,都似乎无法实现。
string strRet;
// hash contains the SHA 1 value of SHA1 (key + temp)
string hash = "ce0037fbbff7a1b68b5794bd73dcc7d63338f115";
try
{
string key = "password";
string temp = "name=bob,withdraw=$200";
for (int i = 0; i < 1000; i++)
{
byte[] buffer = Encoding.ASCII.GetBytes(temp);
SHA1CryptoServiceProvider cryptoTransformSHA1 = new SHA1CryptoServiceProvider();
strRet = BitConverter.ToString(cryptoTransformSHA1.ComputeHash(buffer)).Replace("-", "");
strRet = strRet.ToLower();
MessageBox.Show(strRet);
if (strRet.Equals(hash))
{
MessageBox.Show("Hash are equal !");
MessageBox.Show(temp);
}
temp = key + temp + "2";
}
MessageBox.Show("The End !");
}
catch (Exception)
{
MessageBox.Show("There is a Error !");
}
请问有人能通过提供一个具体的例子来指导我,让我可以进行哈希并理解并证明作者在文章中对这两种哈希方法所声称的内容吗?非常感谢提供任何帮助。