从下面列出的链接中阅读文章后:
http://news.ycombinator.com/item?id=910203
我现在正试图证明和理解为什么下面列出的哈希是不安全的,程序员不应该练习。
H(k || m) --> SHA1("密钥" + "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 !");
}
有人可以通过提供一个指定的示例来指导我,我可以散列、理解和证明作者在文章中对这两种散列方法的主张。提前感谢您提供的任何帮助。