以下のリンクから記事を読んだ後:
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 コードが必要です。
2 番目の例も壊れており、このブログ投稿の主題です。メッセージの後にキーを追加すると、推測できない秘密が最後にあるため、データでハッシュを駆動し続けることができなくなります。
作成者の主張を証明しようとして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 !");
}
ハッシュ方法の両方について記事で著者が主張していることをハッシュし、理解し、証明できる特定の例を提供することで、誰かがこれについて私を導くことができますか? 提供されたヘルプに事前に感謝します。