web-dev-qa-db-ja.com

ハッシュ関数が一方向なのはなぜですか?アルゴリズムを知っているのに、アルゴリズムから入力を計算できないのはなぜですか?

パスワードハッシュをリバースエンジニアリングできないのはなぜですか?

私は何年も前にこれを調べて、たくさん読んだことがありますが、それができない理由の説明が見つかりません。例を使用すると、質問を理解しやすくなり、物事を単純に保つために、ソルトを使用しないハッシュアルゴリズム( LanMan )に基づいてこれを行います。

私のパスワードが「パスワード」だとしましょう。 LanManはこれをハッシュしてデータベースに格納します。クラッキングプログラムは、提供されたパスワードの推測をハッシュすることにより、これらをブルートフォースにすることができます。次に、生成されたハッシュをデータベース内のハッシュと比較します。一致する場合は、パスワードが計算されます。

なぜ、パスワードクラッカーがプレーンテキストのパスワードをハッシュに変換するアルゴリズムを知っている場合、ハッシュからパスワードを計算するプロセスを逆にできないのですか?

この質問は今週のITセキュリティ質問でした。
詳細については、2012年2月24日ブログエントリをお読みください。または自分で送信今週の質問。

231
Mucker

簡単な「パスワードハッシュアルゴリズム」を考案して、その仕組みを説明します。このスレッドの他の例とは異なり、いくつかの奇妙なパスワード制限に耐えることができれば、これは実際に実行可能です。パスワードは2つの大きな素数xおよびy。です。次に例を示します。

x = 48112959837082048697
y = 54673257461630679457

xyをO([〜#〜] n [〜#〜] ^ 2)時間で計算するコンピュータプログラムを簡単に作成できます。ここで、-[〜 #〜] n [〜#〜]xおよびy。の桁数です(基本的に、数字の場合、4倍の時間がかかりますアルゴリズムはより高速ですが、それは重要ではありません。)xyをパスワードデータベースに保存します。

x*y = 2630492240413883318777134293253671517529

5年生の子供は、十分なメモ用紙を与えられて、その答えを理解することができました。しかし、どのようにそれを元に戻すのですか?人々が大きな数を因数分解するために考案した多くのアルゴリズムがありますが、最高のアルゴリズムでさえ、乗算の速さに比べて遅いですx by y。そして、これらのアルゴリズムはどれもできませんでした数が非常に少ない場合(例:x = 3、y = 5)を除き、5年生が実施する。

それが重要なプロパティです:計算は、逆方向よりも順方向に実行する方がはるかに簡単です。多くの問題では、完全に新しいアルゴリズムを発明して、計算を逆にする必要があります。

これは、単射または全単射の関数とは関係ありません。パスワードを解読するとき、同じパスワードを取得しても、同じハッシュで異なるパスワードを取得しても、多くの場合、問題になりません。ハッシュ関数は、逆にして取得するのが難しいように設計されていますすべての回答、同じハッシュを持つ別のパスワードでも。暗号で言えば、プリイメージ攻撃に対して脆弱なハッシュ関数はまったく価値がありません。 (上記のパスワードハッシュアルゴリズムは、x <y。のルールがある場合に単調です)

暗号化の専門家は何をしていますか?ハッシュ関数(元イメージ)を逆にする新しいアルゴリズムを理解しようとすることがあります。彼らはあなたが言うことを正確に行います:アルゴリズムを分析し、それを逆転させようとします。一部のアルゴリズムは以前に逆転しており、他の逆転はしていません。

読者のための演習:パスワードデータベースに次のエントリが含まれているとします。

3521851118865011044136429217528930691441965435121409905222808922963363310303627

パスワードは何ですか? (これは実際にはコンピュータにとってそれほど難しくありません。)

脚注:実際に選択するパスワードの数が少ないため、適切なパスワードハッシュは、逆方向の計算だけでなく、順方向の計算にも時間がかかり、辞書攻撃を遅くします。もう1つの保護層として、ランダム化されたソルトは、事前計算された攻撃テーブル(「レインボーテーブル」など)の使用を防止します。

脚注2:ハッシュ関数を元に戻すのが難しいことをどうやって知るのですか?残念ながら、私たちにはありません。ハッシュ関数を逆にする簡単な方法がわからないだけです。逆にするのが難しいと思われるハッシュ関数を作成することは、ハッシュ関数の設計の聖杯であり、まだ実現されていません(おそらく実現しないでしょう)。

235
Dietrich Epp

ここで答えを出す最初のステップは、@ DietrichのNiceのように、逆方向よりも一方向に実行することがはるかに困難で、速度の突破口を見つけるための多くの試みに抵抗してきた関数の例を見ることです。しかし、問題は複雑なので、もう少し具体化してみます。

多くの人々は、ハッシュ関数が実際にはなんとなく魔法であると考えるトラップ(へ)に陥っているようです。ハッシュと呼ばれているからといって、逆方向に実行する必要があります。これは、セキュリティフォーラムでそれについて考えるための健全な方法ではありません。それはしばしば実際には間違っています。また、関数の基本的な数学的定義を ドメインからイメージへのマッピング とすると、理論上は常に誤りです。

原則として、すべてのハッシュを逆にすることができます。 (ブルートフォースの場合のように)乱雑で残忍な場合があり、今日のハードウェアでは非現実的に長い時間がかかる場合があり、長期的にも耐えられる場合がありますが、数学的には単に時間の問題です。 @muckerが述べたように、すべての情報は元のパスワード(または、少なくとも機能するパスワード)を見つけるためにあります。それを忘れると、定期的にニュースを作り出す可能性のあるパスワードをチェリーピッキングする巧妙なヒューリスティックの危険性を忘れてしまいます。ハッシュは技術的な問題であり、主な課題は効率の問題です。ハッシュを与えられたパスワードを見つけるのに費用をかける方法です。そのような考え方の主な結果の1つは パスワードハッシュを作成することの重要性slow です。

そして、ハッシュの科学と数学は徐々に良くなっています。ハッシュが本当に難しいという証拠はまったくありません。 @Dietrichの答えは、理想的なハッシュ関数mightがどのように可能であるかを示す良い方法です。しかし、最高の暗号アルゴリズムの証明がないことを説明している本当の専門家を見てください: 対称暗号とダイジェストアルゴリズムのセキュリティ主張の背後にある数学モデルは何ですか?

LanManが質問で引用されたという事実は、ハッシュを理想化することを回避する必要があるというより多くの証拠です。 LanManは理想的なハッシュ関数以外のものであり、少しの分析と少しのブルートフォーシングの組み合わせによって簡単に打ち負かされます。恐ろしいハッシュ関数のもう1つの一般的な例については、 MySQL OLD_PASSWORD cryptanalysis? を参照してください。

だから、罠から身を戻してください-それに陥るのは片道の旅行である必要はありません。ハッシュは元に戻せることを認識し、ハッシュを元に戻す最善の方法を探すときは、信頼できるセキュリティの考え方をアクティブに保ちます。これは、本当に元に戻すことが難しいものを見つけるための最良の方法です。私は、bcryptやPBKDF2やscryptなどのベストプラクティスにアスペションをキャストするつもりはありません。しかし、優れたプログラマーでさえ、この問題を頻繁に誤解していることは明らかです。したがって、それらの使用方法に注意し、独自のものを発明しようとしないでください。

17
nealmcb

これが暗号化ハッシュ関数のしくみであるため、それらは(プレーンからハッシュへの)一方向の数学関数です。アルゴリズムは、それを回避し、衝突を回避するために特別に作成およびテストされています(2つの異なるプレーンテキストが同じハッシュを生成します)。

詳細は wikipediaで ですが、記事の主なポイントは次のとおりです。

理想的な暗号ハッシュ関数には、4つの主要なまたは重要なプロパティがあります。

  • 与えられたメッセージのハッシュ値を計算することは簡単ですが(必ずしも迅速ではありません)
  • 与えられたハッシュを持つメッセージを生成することは不可能です
  • ハッシュを変更せずにメッセージを変更することは不可能です
  • 同じハッシュで2つの異なるメッセージを見つけることは不可能です

ハッシュ関数に対する攻撃のほとんどは、衝突の検出(2つの異なるプレーンテキストが同じハッシュに一致する)または何百万ものハッシュを事前に生成し、それを生成したプレーンが見つかるまで比較することに基づいています。

長い歴史:ハッシュアルゴリズムがreverse-engineerableであるか、そのように攻撃される可能性がある場合、それは良いハッシュアルゴリズムではありません。

パスワードについては、BCryptを使用して調査します この投稿 にはそれに関する多くの情報があります。

12
coredump

ハッシュに単一ビットを使用するハッシュ関数を想像してみてください。したがって、ハッシュは0または1のいずれかになります。

また、ハッシュ関数がデータのすべてのバイトを合計するとします。データが偶数の場合、ハッシュ値は0です。データが奇数の場合、ハッシュは1です。

ハッシュ関数をリバースエンジニアリングしてもデータを回復できなかった理由がわかりますか?

これは実際のハッシュアルゴリズムでも同じです。式だけが、先ほど説明した関数よりもはるかに優れています。

あなたの難しさは、パスワードでの使用に関してハッシュを検討していることかもしれません。 128ビットのハッシュから8文字のパスワードを回復できない理由は明らかではありません。ただし、パスワードに使用するハッシュ関数は、テラバイト全体のデータのハッシュを計算するためにも使用でき、ハッシュは128ビットのデータしか使用しません。明らかに、128ビットのハッシュをリバースエンジニアリングしてテラバイトのデータを復元することはできません。

また、1テラバイトのデータのすべての順列があると仮定すると、同じハッシュを生成するさまざまなデータが大量に存在することになります。結局のところ、データの2 ^ 127を超える順列がある場合、同じハッシュを持つ2つの異なるデータに遭遇する可能性が高くなります。

8
user1068775

本質的に元に戻せないアルゴリズムがあります。それらは、アルゴリズムの正確なステップを知っていても、AをBから回復できないような方法で、入力Aを出力Bに変更します。

非常に単純な例:パスワードの各文字をASCII値に変換し、すべての値を合計します。結果から元のパスワードを回復する方法はありません。

4
Massimo

以前の回答で人々が見逃している問題の1つの側面があります。これがハッシュ関数の多対1の性質です。 (ほとんどの)ハッシュ関数は固定長の出力(256ビットなど)であるため、技術的にはすべてが同じ値にハッシュされる文字列が無限に存在します。

たとえば、512ビットの文字列(そのうち2 ^ 512が含まれる)をすべて使用するとします。ハッシュ関数の出力は2 ^ 256のみです。したがって、ハッシュ関数の出力ごとに、その値にハッシュされる約2 ^ 256の512ビット文字列があります。ハッシュ関数が実際にランダム関数であるかどうかわからないので、大まかに言って、それはわずかなバイアスを持っている可能性があります。

したがって、ダイジェストが与えられた場合、同じ値にハッシュされる文字列が多数あります。したがって、ユーザーのパスワードを出力するように「ハッシュ関数の逆転」を定義した場合、逆転関数は、与えられたダイジェストをもたらす可能性のある無限の文字列をどのように処理しますか?

2
mikeazo

「ハッシュ関数が一方向であることがなぜ重要なのですか?」これはセキュリティプロパティです。

今日一般的に使用されている「ハッシュ」(または「メッセージダイジェスト」と呼ばれる)には2種類あります。 1つはプレーンメッセージダイジェストで、CRC32などのチェックサムアルゴリズムとしてよく知られています。アルゴリズムは、入力の1ビットの変更によって異なるダイジェスト値が生成されるように設計されています。これの主な目的は、メッセージが誤って破損されないようにすることです。 CRC32チェックサムはすべてのTCP/IPパケットに存在し、不一致の結果、エラーを修正するために再送信されます。

メッセージダイジェストは、メッセージの「署名」の一部として暗号化でよく使用されます。メッセージは送信者によって秘密鍵で暗号化され、誰でも公開鍵を使用して、送信者だけが暗号化したことを検証できます。ただし、RSA公開鍵暗号化は、鍵サイズ(256バイト)よりも小さいメッセージのみを暗号化できます。これは、最も有用なメッセージよりもはるかに短いです。メッセージダイジェストアルゴリズムは、RSAキーよりも小さい値を生成します。したがって、メッセージの代わりにダイジェストを暗号化することにより、RSA署名を任意のサイズのメッセージで使用できます。

しかし、通常のメッセージダイジェストは攻撃者に対して安全ではありません。文字の値を合計するだけの非常に単純なチェックサムを考えます。あなたがそのようなチェックサムに署名した場合、同じチェックサムを生成する他のメッセージを交換することができ、署名が一致して、被害者をだますことができます。

メッセージダイジェストのもう1つの一般的な用途は、保存中のパスワード保護です。システムに保存する前にパスワードを暗号化すると、キーを知っているシステム管理者がすべてのパスワードを解読できる可能性があります。 (最近、いくつかのWebサイトがハッキングされたときにこの問題に気づいたかもしれません。)

これらの問題を回避するには、「暗号的に安全」な別の種類のハッシュが必要です。安全なハッシュアルゴリズムには、2つの追加プロパティ衝突耐性非可逆性があります。

衝突抵抗とは、同じダイジェストを生成するメッセージを見つけられないことを意味します。そうすれば、邪悪なメッセージをあなたの良いメッセージと交換することができません。

非可逆性のプロパティは、ダイジェストをプレーンテキストに戻すことができないため、ユーザーのパスワードのように元のメッセージを復号化できないことを意味します。

ダイジェストの作成は暗号化と非常によく似た問題であり、元のデータに関する情報が漏洩しないようにデータをスクランブルする必要があります。同じ数学は衝突をうまく作成する方法についての手がかりを与えてはならないので、それはさらに難しいです。

1
John Deters

理由はたくさんあると思いますが、1つは明らかです。ハッシュ関数によって生成されたダイジェストには有限のビットがあるため、無限の情報を含めることはできません。ただし、ハッシュ関数を使用して、無限情報の入力をハッシュできます。入力は実際には何でもかまいません。

衝突を見つけるのは困難ですが、答えはありません。本当の困難は、元のデータが実際に特定のダイジェストに一致する唯一の可能な入力であることを証明することです。私はあなたが1つの入力を計算することは決してなく、それがダイジェストに対する唯一の答えであると主張するかもしれないと思います。

0

他の人たちは、優れた暗号化ハッシュ関数を元に戻すのが難しい理由を説明していますが、 このWikipediaの記事 によると、LanManは設計が不十分で、比較的簡単に元に戻すことができます。

よく研究されたブロック暗号であるDESに基づいていますが、LMハッシュは実装にいくつかの弱点があるため、ハッシュからパスワードを決定できるため、真の一方向の関数ではありません...ブルートフォース攻撃を実装することによりそれぞれの半分で、現代のデスクトップマシンは、数時間で英数字のLMハッシュをクラックできます... 2003年に、レインボーテーブルテクニックの実装であるOphcrackが公開されました。特にLM暗号化の弱点を対象とし、数秒で事実上すべての英数字LMハッシュをクラックするのに十分な事前計算済みデータが含まれています。

0
James