web-dev-qa-db-ja.com

何もしないのではなく、不適切なハッシュアルゴリズムを使用する方が良いですか?

パスワードのハッシュに推奨されるアルゴリズム(bcrypt、scrypt、PBKDF2など)を提供していないシステムにパスワードを保存する必要があります。どれも使用する前に、不適切なアルゴリズム(SHA-1やSHA-2ファミリーなど)を使用する方が良いでしょうか?


追加情報:私はそのシステムで唯一の格納パスワードになるため、1)パスワードが2回使用されないことを保証し、2)パスワードが非常に高いエントロピーを持つことを保証します。

45
JFB

あなたの質問に対する本当の答えは、あなたがそれらを適切に保護することができないなら、単にそこにパスワードを保存しないことです。

「システムは適切なパスワードハッシュアルゴリズムをサポートしていません」は、ユーザーのセキュリティを危険にさらす有効な言い訳にはなりません。強力で適切に構成されたアルゴリズムを使用してパスワードを適切にハッシュする方法を見つけるか、パスワードを保存しないでください。

しかし、あなたの質問に直接答えを提供するために:はい、何かは何もないよりはましです。 SHA-1またはSHA-2は、プレーンテキストよりも明らかに改善されています。

「それではパスワードはどこに行くべきか?」質問-言い回しに基づいて、システムにパスワードを保存する必要があるソフトウェアの新しい機能/要求があると想定しています。

システムが(最新のセキュリティ標準により)パスワードを適切かつ安全に保存できない場合、私は(個人的に)要求を拒否します。レガシーシステムの制約のため、またはビジネスユースケースを緩和するために、意図的に不十分なセキュリティを実践することは、セキュリティの実践としては不適切です。私には、2つの実行可能なオプションがあることをリクエストした人に通知します。

  1. 最新のセキュリティプラクティス(適切な暗号化パスワードハッシュなど)をサポートするシステムに完全にオーバーホールする必要があります。

  2. セキュリティを危険にさらす可能性があるため、既存のシステムに新しい機能や要求を追加することはできません。

117
dFrancisco

はい、弱い暗号ハッシュはハッシュなしよりも優れています。

パスワードをハッシュ化する理由は、パスワードdbが盗まれた場合です。

  1. 攻撃者が平文のパスワードを簡単に入手できないようにします。
  2. 攻撃者が同じパスワードを持っているユーザーを知るのを防ぎます(これは、各ユーザーに一意のソルトを与えることによって達成されます。

1は軍拡競争です:攻撃者がブルートフォースハッシュクラッキングを実行するためにより多くの電力を消費するように、大きくて遅いハッシュ関数を使用したいとします。攻撃者はsomeクラッキングを実行する必要があるため、SHA-1/2の単一の反復はハッシュなしよりも優れています。 salted SHA-1/2を1回繰り返すと、クラッキングを強制的に実行します事前に計算されたRainbowテーブルを使用できない場合。作業係数の高い、より洗練されたパスワードハッシュ(argon2、bcrypt、または古いscrypt、pbkdf2)に移動すると、クラックの電力コストがさらに上昇します。

ソルト化された暗号ハッシュ(SHA-1、SHA-2などのパスワードに推奨されていないものでも)を使用すると、2の利点があります。


基本的に、PBKDF2はSHA-1/2の反復処理とソルト処理を行うだけなので、PBKDF2の実装をググリングして、それをエミュレートするSHA-1/2の周りにラッパーを構築します(または、より完全に、実際に実装します) PBKDF2)。

48
Mike Ounsworth

他の人が言ったように、可能であれば、プラットフォームの言語で強力なスタンドアロン実装を見つけるようにしてください。

ただし、強力なハッシュを使用できない場合は間違いなくハッシュが弱い場合でもユーザーのパスワードをハッシュする必要があります-弱いハッシュでも強力なハッシュが保護されるため)パスワード

Hashcatのようなツールが推測できる場合1秒あたり数十億のパスワード、弱いハッシュは弱いパスワードを保護しません。ただし、セキュリティを意識したユーザーの1人が「SDXBZsRVBKVnXznpLTBMIKhTX」や「afferently-imitatee-snowmelt-heirdom-leeching」などの解読できないパスワードを選択した場合、SHA1のような弱いハッシュでも、そのパスワードはブルートフォースの手の届かないところに置かれます攻撃。

弱いハッシュを使用することで、少なくともシステムに精通したユーザーが自分自身を保護できるようにすることができますシステムが弱い場合でも。 (そして、あなたがstretch-同じアルゴリズムを続けて何千回も使用する能力を持っている場合-これは攻撃者も遅くします)。

しかし、あなたの知識のあるユーザーはパスワードを再利用しないので、これは限られた価値しかありません(ブルートフォースに抵抗するのに十分強力なパスワードを選択したが、他の場所でそのパスワードを再利用したり、人間が解析可能なパスワードを使用している可能性がある「準知識のある」ユーザーは例外ですパスワード選択スキーム...したがって、弱いハッシュを使用しても、これらのユーザーも保護されます)。

すべてのユーザーにとって最良のオプションは、強力なハッシュを使用する方法を見つけることです。

[編集:OPは質問を更新し、彼らはシステムの唯一のユーザーであり、任意のランダムなパスワードを設定できる(これは私にはかなり奇妙に思える;私は知らない「私は唯一のユーザーです」、「いくつかのハッシュアルゴリズムからしか選択できない」、「すべてのハッシュアルゴリズムが弱い」などの奇妙な組み合わせのシステム。どちらにしても、これは一般ユーザーの弱いパスワードを保護することに対する私の懸念をこの特定の質問とは無関係にします。他の回答では、回答の冒頭で、通常はかなり悪いアドバイスをしていることを明確にし、この非常に具体的な質問にのみ適用できるようにします。]

[編集2:「弱いハッシュ」は「悪いハッシュ」と同じではないことに注意してください。不適切なハッシュの例は、descryptです(パスワードが8文字で切り捨てられるため)。したがって、パスワードが強力な場合でも、プロシューマーグレード(6 GPU)のクラッキングシステムでは、8文字の暗号解読ハッシュが10日以内にブルートフォースされる可能性があります。]

30
Royce Williams

この特定の場合のSHA-2は、PBKDF/scrypt/bcryptと同じくらい安全です。反復は不要で無駄です。高エントロピー(256ビット)パスワードを生成し、KDFやソルトさえも忘れてください。

実際、アルゴリズムの既存のプラットフォーム実装がなく、「独自の暗号のローリング」は禁止されているため、PBKDFよりもSHA-2を使用する方が理にかなっています。

それは非常に強力な声明です。ここでの問題の本質は、OPがシステムに保存するパスワードを完全に制御し、OPがシステムに保存する唯一のパスワードになることを知っていることです。

Signal は、ダブルラチェットアルゴリズムでHKDFと呼ばれる構造を使用します。これは、基本的にハッシュアルゴリズムを1回の反復にのみ適用します。

なぜ大丈夫なのですか?

パスワードKDFが存在する理由は1つだけです。それは、低エントロピーパスワードです。ほとんどの人は、CSRNGから生成された128ビットまたは256ビットのキーを覚えていないでしょう。ほとんどの人は、40ビットのランダムな文字列を、それを使用するのに十分な期間記憶することができると思います。

ほとんどすべてのハッシュ関数(MD4、MD5、SHA-1も含むが、プラットフォームにSHA-2があると言ったので、ここで安全にしましょう)には プリイメージ耐性 という機能があります。システムに保存されるすべてのパスワードを制御するので、アプリケーションには十分です。これは、ハッシュが与えられた場合、同じハッシュにハッシュするものを生成することは計算上実行不可能であることを意味します。

少し単純化すると、これらのハッシュ関数の1つのプリイメージを生成する最も実用的な方法は、入力を試行し続けることです。ブルートフォースよりもわずかに優れた の攻撃がいくつかありますが、それらは完全に実行不可能です。ここで、ハッシュ関数に入力することを選択したパスワード/キーのエントロピーが16ビットしかない場合、攻撃者は入力した65536種類の入力すべてを試すことができるため、この耐性プロパティはあまり効果がありません。

パスワードの制御が重要な理由

「パスワード」として入力するものではなく、暗号化キーとして考えてください。選択したハッシュ関数(SHA-256の場合は256ビット)が出力するビット数以上のエントロピーを持つキーをハッシュしている限り、ハッシュの1回の反復を実行するだけでまったく問題ありません。キーの抽出を防ぐために、ハッシュのプリイメージ耐性とキーの高いエントロピーを組み合わせることは、攻撃者が入力した値を推測できないことを意味します。何千回もの反復やビジネス側との議論や抽象的な攻撃についての理由付けをする必要はありません-受容性の高いボス。 FPGA/ASICの抵抗は、ハッシュ関数への256ビットの入力を推測する必要がある場合の問題点です。

推奨事項

ハードウェアRNGまたはCSPRNGを使用して「パスワード」を生成し、内部状態を回復するために使用される可能性のあるシードマテリアルをすべて破棄し、したがってパスワードを破棄します。これらが256ビット長であることを確認してください。システムが非英数字または非ASCIIパスワードをサポートしていない場合、256ビットを生成し、base-64またはbase-26またはバイナリでエンコードします。お気に入り。 (これは、送信する実際のパスワードが32バイトより長くなることを意味しますが、これはエントロピーの助けにはなりません。)

これらのパスワードは暗号化キーのように扱います。理想的には、ハードウェアトークンに保存されます。ハードウェアパスワードマネージャーは、この目的に非常に適しています。 SHA-256ハッシュをシステムに保存し、ハッシュおよび比較してパスワードを確認します。ハッシュが一致する場合でも、生成基準(例:ユーザーが選択した256ビット未満のパスワード)に一致しない、試行されたすべてのパスワードを拒否する必要があります。また、 CSRNG。これは文書化する必要があります。さらに、生成したパスワードの最後に不明瞭なチェックサムバイトを追加すると、パスワードを設定する前にプラットフォームによって検証されます。これにより、最も陽気な無能な人以外は、暗号化キー以外のものをプラットフォームに配置することができなくなります。

公開キーの暗号化

ユースケースは少し変わっています。 PKIのセットアップとエンドユーザーへの対応は、特に公開鍵のようなものでは非常に難しいため、ほとんどの場所ではパスワードを保持しています。あなたがシステムにパスワードを入力する唯一の人のように見えるので、Ed25519またはECDSA公開鍵をシステムに保存し、チャレンジ/レスポンスプロトコルを実装するコードをそこに書き込む方が理にかなっているでしょう(単純なものは、この256-ビット値-ただし、これらのキーを再利用しないように注意してください。誰かがあなたを騙して、ビットコインや犯罪の告白をサインアウトさせる可能性があります)。ここでシステムとインターフェースをとり、秘密鍵を維持するデバイスは、おそらく公開鍵暗号化の強力な実装を備えており、それ自体を認証する問題はありません。正しい答えが得られる限り、署名検証の「自分自身のロール」実装は、サイドチャネル攻撃(その状態全体をビルボードまたはブロックチェーンに置くことを考える)の観点から、世界で最も安全性が低い可能性があります。検証アルゴリズムは秘密鍵にアクセスできないため、問題はありません。

16
John Adams

私はマイクとロイスの答えに同意し、彼らがうまくカバーしたことを繰り返す必要性を感じません。しかし、私はあなたのこのコメントにもっと直接対処したいと思いました:

追加情報:そのシステムでパスワードを格納するのは私だけなので、1)パスワードが2回使用されないことを保証し、2)パスワードのエントロピーが非常に高くなるようにします。

この情報は重要であり、重要ではありません。理由は次のとおりです。

パスワードハッシュの場合

覚えておくことは常に重要ですwhyパスワードをハッシュ化しますが、結局はパスワードの再利用に帰着します。パスワードハッシュが非常に重要である理由は、システムが侵害されてパスワードが盗まれた場合、侵害されたのはサイトへのアクセスだけではなく、ユーザーが同じメール/パスワードを再利用したすべてのサイトへのアクセスであるためです。 (私たちが知っているように)多く発生する組み合わせ。パスワードハッシュとは、ユーザーを自分自身から保護することです。絶対に誰もがすべてのサイトで強力で一意のパスワードを使用している場合、パスワードハッシュの必要性ははるかに少なくなります。ハッカーがデータベースダンプへの読み取り専用アクセスを取得する可能性があるユースケースがあるため、ハッシュされたパスワードは、攻撃者がシステムに実際にアクセスするのを防ぐことができます。あらゆる場所でパスワードを使用すると、パスワードハッシュは、今日のように絶対的に重要な必要性ではなく、二次的な関心事になります。

したがって、システムのすべてのユーザーが強力で一意のパスワード(つまり、他のサイトで使用されていないパスワード)のみを使用することを保証できる場合、SHA2のような単純なものでも、実際には完全に合理的な選択だと思います。より良い機能が利用可能かどうかに関係なく。

ただし、ビジネスニーズの変化

ただし、想定を再確認することをお勧めします(強力な一意のパスワードのみがシステムで唯一のものになります)。重要なビジネス領域でのそのような仮定に依存するために、ビジネスニーズが過去に頻繁に変化するのを見てきました(これはそうではないかもしれません-明らかにこれが何をするのかわかりません)。問題は、ビジネスの変化が必要であることです。多分それは私だけかもしれませんが、私の経験では、一時的または数人に限定することを意図していたものは、必然的に会社の全員が使用する重要なビジネスアプリケーションに変わり、突然あなたは重要なビジネスを保護する弱いパスワードスキームを持っていますインフラ。人々が試してみて手を抜こうとしているからといって、常に発生するとは限りませんが、12か月後には、優れたパスワードハッシュを使用しなかったことを忘れたり、立ち去ったりして次の人はそれをしませんt調査するか、期限に間に合うように圧力をかけられて、忘れるか、または、または、または...

私の経験では、セキュリティがhardであるからではなく、優れたセキュリティプラクティスに時間を費やす必要性(別名:お金)を理解していないために、ビジネスがセキュリティ侵害を経験することになります。確かに、そうですnow優れたパスワードハッシュスキームは問題ではありませんが、将来的に変更されないことを本当に保証できますか?今適切なパスワードハッシュを入力する時間がない場合、ニーズが変化し、それが突然問題になったときに、すぐにそれを実行する時間があることを保証できますか?

もちろん、結局のところ、すべてのビジネスはお金を稼ぐ必要があり、時には「これを簡単にするために、これを手に入れよう」というのは完全に合理的な答えです。ただし、その決定は頻繁に行われるため、企業がセキュリティホールを抱えたシステムになってしまうため、注意が必要です。会社として、あなたは自分のためにそのバランスを見つける必要があります。問題は、企業がセキュリティを慢性的に弱体化させた場合、最終的に最も被害を与えるのは顧客です。

4
Conor Mancone

パスワードのハッシュ化に推奨されるアルゴリズム(bcrypt、scrypt、PBKDF2など)を提供していないシステムにパスワードを保存する必要があります。どれも使用する前に、不適切なアルゴリズム(SHA-1やSHA-2ファミリーなど)を使用する方が良いでしょうか?

あなたの質問に対する厳密な答えはイエスです。その理由は、高速ハッシュは弱いパスワードを保護しないが、非常に強力なパスワードを保護するためであり、プレーンテキストよりも厳密に優れているからです。

ただし、SHA-1またはSHA-2を使用している場合、PBKDF2を使用しない言い訳は(もしあれば)非常に少ないです。ええ、一般的なアドバイスは「自分の暗号をロールバックしないでください」ですが、SHA-1またはSHA-2を持っている場合、それはすでにPBKDF2の主要なビルディングブロックであり、パスワードハッシュでPBKDF2の独自の実装を作成する場合は、そうでない場合よりも悪くなることはほとんどありません。関連するRFCとセクションは次のとおりです。

彼らが「疑似ランダム関数」と言うときは、いくつかのHMACバリアントを使用する必要があります(理想的にはHMAC-SHA-512ですが、どれでも使用できます)。ライブラリにはすでにHMAC実装が含まれている可能性がありますが、そうでない場合でも、パスワードハッシュは、独自の実装の場合よりも悪くなることはありません。

2
Luis Casillas

あなたの質問に答えるには:はい、アクセスできる最良のアルゴリズムを使用します。複数ある場合、それらを組み合わせることができます(注:パスワードの連結(例:sha1(password)+ md5sum(password))は、攻撃者が推測したいハッシュを選択する可能性があるため、推測に対してより脆弱ですが、衝突ははるかに少ないです。おそらく、両方のパスワードが一致する必要があるため、パスワードごとにランダムな異なるソルトを使用してください。

あなたのシステムは「パスワードのハッシュに推奨されるアルゴリズムのいずれも提供していない」と言います。その仮定を再検討することをお勧めします。

最近のほとんどすべてのプログラミング言語には、安全なハッシュの実装があります。事前に作成され、事前にインストールされたライブラリに実装する必要はありません。たとえば、プログラムがCで記述されている場合、スタンドアロン関数としてCのハッシュの実装を見つけることができます。 Arduinoのような小さなプロセッサでさえ、既成のbcryptとPBKDF2があります。関与する余分な労力は最小限です。自分で実装することもできます(ただし、十分に注意して、十分にテストしてください)。

例外があることは間違いありませんが、例外は多くありません。

1
AMADANON Inc.

上記の優れた答えに沿って、私は無料だが反対の答えを出したいと思います。

いいえ。弱いハッシュを使用すると、ハッシュをまったく使用しない場合よりも悪いになります。

弱いハッシュは、セキュリティのような錯覚を与えます。

あなたとあなたのマネージャーはハッシュが実際のセキュリティを提供しないことを現在理解しているかもしれませんが、将来のマネージャーまたは開発者はハッシュが安全であると考えるかもしれません。これらの人々は、問題のハッシュを使用して追加情報を保存することに決めるかもしれません。

ハッシュがそもそも安全でないことを経営陣が単に理解できないリスクもあります。セキュリティ開発に投資するという決定に直面したとき、彼らは「現在のシステムはすでにハッシュされているため、ハッシュはベストプラクティスと見なされているため、「現在のシステムで十分です」と決定する場合があります。

0
Gregory Currie

はい、低品質のハッシュでも平文でパスワードを保存するよりもはるかに優れています

あなたが更新を理解している場合、他の誰かが認証を行い(あなたとあなたのデータベースとは無関係です)、あなたはパスワードの重複データベースを検出するためだけにパスワードハッシュデータベースを使用しますか?パスワードエントロピーを決定する要件はプレーンテキストに基づいており、パスワードハッシュの格納とは関係ありませんよね?

次に、ハッシュデータベースに、salt + plaintextの計算されたsha2ハッシュのほんの一部を格納できます(たとえば、sha256から返された32バイトのうち、下位8バイトのみを格納します)これは、実際には誤検出のない重複を検出するのに十分ですが、データベースが盗まれた場合に攻撃者がRainbowテーブルを使用して元のパスワードを推測するのに十分ではありません。

(免責事項:重複したパスワードの検出だけでなく認証を行っている場合は、ハッシュの一部を削除するよりも明らかにひどい考えになります!)

0
Matija Nalis

はい、弱いハッシュを使用する方が、使用しないよりはましです。

行政のやり方も考えるべきだと思います。データベースを管理している場合(ただし、構造を変更することは許可されていませんが、その理由を知っている人は...)、あなたが最も整数的な人物であり、その情報に害を及ぼさない場合でも、プレーンテキストのパスワードは表示されません。ことわざのように:機会が泥棒になります。

0
Lithilion

はい、単純なハッシュを使用するよりも、絶対にハッシュを使用しない方が確実です(どのようにimplementシステムを表示しているのかはわかりますが、適切な処理を妨げている原因はわかりません)。

ただし、「追加情報」の編集を考えると、塩も必要ない、と言うほど大胆な場合があります。それが良い設計であることを意味するわけではないので、お勧めしませんが、保証を真剣に考えている場合は、厳密に言えば、妥当なサイズの単純で安全なハッシュで十分です。

そもそもなぜパスワードの保存についてそんなに大騒ぎするのですか?通常、パスワードは低エントロピーであり、ハッシュされた場合でも、ハッシュ関数が非常に高速であり、簡単に並列化できるため、パスワードを推測するかなりのチャンスがあります。安価なショートカットを提供するRainbowテーブルが存在します。したがって、ハッシュされた後でも解読できなくても、必ずしもパスワードが回復不能であるとは限りません。
原則として、無限の時間が与えられれば、すべてのシステムのすべてのパスワード(または少なくとも機能するパスワード)を回復できます。これは、ハッシュ関数への出力が有限数であるという事実の結果です。したがって、準網羅的な検索では、some入力シーケンスは、必ず機能する出力を生成する必要があります。
幸運にも攻撃者には無限の時間がないため、私たちの仕事は、有限の時間内で有限のエネルギー供給で機能する入力シーケンスを見つける合理的な機会がないことを確認することです。

さて...あなたはあなたが唯一のユーザーであり、あなたができると言います保証パスワードはランダムで高エントロピーです。これにより、推測に関するほとんどの懸念が排除されます。

「妥当な」ダイジェストサイズが与えられた場合、これは、Rainbowテーブルでハッシュを見つける可能性が最小(ゼロ、多かれ少なかれ)であり、ブルートフォースでハッシュを見つける可能性が多かれ少なかれゼロであることを意味します。 SHA-512は言うまでもなく、SHA-256ダイジェストブルートフォースを破壊する方法はありません。そのアイデアは、物理学がどのように機能するかについての私たちの理解と互換性がありません。
ダイジェストが十分に大きく、パスワードが(指定したとおりに)一意でランダムで高いエントロピーであることが保証されている場合...実際には、一度ハッシュするだけで十分です。

もちろん、通常、システムはcannotがその保証(またはanyの保証)を提供しても、確実に機能するはずです。したがって、それは最高のデザインではありません。

0
Damon

うん、大丈夫だよ。 SHA1と2は、エントロピーの高いパスワードハッシュを保存するのに依然として非常に強力であり、ブルートフォースからの適切な保護を提供します。 SHA2はSHA1よりも優れた保護を提供します。SHA2の脆弱性は、最初の平文がすでにわかっている衝突の作成に関連するため、このシナリオには関係ありません。

0
Jake