web-dev-qa-db-ja.com

私が5歳のようにBCryptを説明する

私はこれが少し広いことを知っていますが、私は5のように説明することによってこのアルゴリズムの機能を理解したいと思います。BCryptとblowfishの違いを知りたいのです。塩?

私は読んでいましたが、情報が低レベルで表示されており、それほど深く知りたくありません。簡単な説明(塩、ビットなどの基本を知っている)を取得したいと思います。

たとえば、パスワードの最初の部分は次のとおりです。

$2$: Blowfish-based crypt ('bcrypt')

そして2番目はラウンドです。例えば、 $10$は2 ^ 10の鍵拡張ラウンドを示しますが、それは正確にはどういう意味ですか?

答えの例は次のとおりです。

  1. まず、アルゴリズムXでソルトを作成します
  2. 次に、Xの乱数を取得します
  3. 次に、ラウンドでXを実行します

このような何か、それが明確であることを願っています。

5
Skizo-ozᴉʞS

BcryptBlowfish 対称鍵ブロック暗号を使用し、3つのパラメーターを受け入れます。コスト、ソルト、パスワード。

  • コストはシステムレベルによって決定されるため、管理者はパスワード検索攻撃のタイミングを決定できます。 hashcat を参照してください。反復回数はiter= 2^costとして決定され、コストは2から31の間です。

  • ソルトはランダムな16バイトです。 \dev\urandomとして、任意の適切なランダムソースを生成できます。

  • パスワードは、処理されるユーザーのパスワードです。パスワードのサイズは1〜72バイトです。

  • Bcryptの出力は24バイトです。

Bcryptは、テキストOrpheanBeholderScryDoubtをチェーンECBモードで暗号化します。

 state = EksBlowfishSetup(cost, salt, password) //Special key scheduling 
 ctext = "OrpheanBeholderScryDoubt"
 repeat (64)
      ctext = EncryptECB(state, ctext)
 return Concatenate(cost, salt, ctext)

コストの更新

EksBlowfishSetup(拡張キーセットアップ)はまもなく次のようになります。

state = InitialState()
state = ExpandKey(state, salt, password)
repeat (2^cost)
    state = ExpandKey(state, 0, password)
    state = ExpandKey(state, 0, salt)

コストは、BCryptの上記の機能に影響を与えます。コストが増加すると、繰り返しループは指数関数的に実行されます。 この回答の表 からわかるように、これにより攻撃時間が増加します。 hashcatと比較したい場合は、 Tesla K80 のベンチマークを参照してください

注:Bcryptは古い(1999)ので、 Argon2iパスワードハッシュコンテスト

7
kelalaka

ハッシュと暗号化

Bcryptとblowfishの最大の違いは、blowfishは対称暗号化アルゴリズムであり、bcryptはハッシュアルゴリズムであることです。 (これは特殊なハッシュアルゴリズムですが、後で説明します。)

暗号化(Blowfishが行うこと)

対称暗号化アルゴリズムは秘密鍵と平文を受け取ります(「メッセージ」という用語が通常使用され、変数mは通常それを参照するために使用されます)暗号文を出力します、c。暗号文は、暗号化時に使用されたものと同じ[^ same]秘密鍵でのみ元のメッセージに変換し直すことができるという考え方です。

[^ same]:ここでは、中心的なアイデアと概念に焦点を当てるために、ほぼ正しい答えを出しています。私の答えが正確に当てはまらない場所を認識してくれる人が、説明の目的で私に多少の余裕を与えてくれることを期待しています。

したがって、アリスはキー13でメッセージ「夜明けの攻撃」(これはnotblowfishですが、対称暗号化です)を暗号化して暗号文を生成する可能性があります " Nggnpx ng qnja」。彼女はその暗号文をボブに送信でき、ボブが鍵が13であることを知っている場合、ボブは暗号文を元のメッセージに変換し直すことができます。時々、アリスは他の人にメッセージを送りたくないが、後で読むために自分のためにそれを保存したいです。これらのケースは、アリスが将来のアリスにメッセージを送ると考えることができます。

(例で使用した暗号化の代わりに)Blowfishを使用すると、鍵を持っていない人が暗号文から元のメッセージ(長さと存在以外)について何かを知ることは事実上不可能です。余談ですが、AESはBlowfishよりも望ましい対称暗号化アルゴリズムですが、私は説明でBlowfishを引き続き使用します。

ハッシュ

暗号化ハッシュアルゴリズム(bcryptは特別な種類ですが、いくつかの追加機能がありますが、簡単なケースから始めます)はキーを使用せず、実際には元に戻すことができません。したがって、SHA256のような暗号化ハッシュアルゴリズムは、「JaguarsRule!」のようなメッセージ(パスワードとしましょう)を受け取ります。そしてそれをハッシュに変換します。

$ echo -n 'JaguarsRule!' | shasum -a256
13f26e5a60e402d895c5ce1d9492d080563c5079a8b5f52a25953fd24a2cb1da  

暗号化ハッシュのいくつかの特性の1つは、「JaguarsRule!」を適切に計算できないことです。 13f26e5a60e402d895c5ce1d9492d080563c5079a8b5f52a25953fd24a2cb1daから。この場合、キーはありません。

したがって、このような単純なハッシュメカニズムは、サーバー上のパスワードをチェックするための良い方法のように思えるかもしれません。ユーザーがログオンするWebサービスを実行しているとします。ユーザーがいるとします。ユーザー名jasonで、パスワードJaguarsRule!を使用して自分のアカウントを設定するとします。サーバー上の内容を読み取ってJasonのパスワードを知られるようにしたくないので、パスワード自体は保存しません。代わりに、そのハッシュを保存します。

Jason(またはjasonのふりをした人)がサーバーにログインすると、入力されたパスワードを取得してハッシュ操作を実行し、保存されているハッシュを比較します。ハッシュが一致すると、システムは正しいパスワードが入力されたことを認識します。

塩とスロークッキング

SHA256のような一般的な暗号化ハッシュを使用する上記のスキームは、1つのことを除いてうまく機能します。人々が推測可能なパスワードを選択することです。人々がwZFoO_SKrgEwのようにJaguarsRule!のようなパスワードを使用する可能性が高い場合、bcryptのような特殊なハッシュ関数は必要ありません。しかし、人間である人々は、十分に大きなスペースでパスワードをランダムに均一に選択することはありません。代わりに、可能なパスワードを他のパスワードよりもはるかに選ぶ可能性が高くなります。

システムの別のユーザーpillboyについて考えてみます。ピルボーイはジャクソンビルジャガーのファンでもあり、たまたま彼のパスワードとしてJaguarsRule!を選んだ。 (無塩)ハッシュを使用すると、Pill BoyのパスワードのハッシュはJasonのパスワードのハッシュと同じになります。攻撃者はハッシュを比較するだけで、2人のユーザーが同じパスワードを持っていることを確認できます。

さらに、攻撃者が何らかの方法でJasonのパスワードがJaguarsRule!であることを発見した場合、攻撃者はPill Boyのパスワードをすぐに知ることができます。さらに、最も一般的なパスワードのハッシュの大きなリストを作成する可能性があります。

これに対する解決策は、パスワードをハッシュする前に固有のものでパスワードをソルトすることです。したがって、最初にJasonのパスワードのハッシュを作成するとき(Jasonが最初にサインアップしてパスワードを作成するとき)には、ランダムなものを追加します。この時点で、システムがソルト9cb3779f69e271c1を作成するとします。次に、ハッシュする前にパスワードの前に貼り付けます。したがって、実際には9cb3779f69e271c1JaguarsRule!のようなものをハッシュしています(これは実際にソルトが追加される方法ではありませんが、これはソルトの目的を説明するのに十分近いものです)。 9cb3779f69e271c1JaguarsRule!のハッシュは、JaguarsRule!のハッシュとは完全に異なります。

システムは、パスワードを検証するときにソルトが何であったかを知る必要があります。そのため、Jasonのユーザー名とともにソルトとハッシュが保存されます。 Pill Boyがアカウントを作成すると、ランダムに生成された別のソルトが設定されるため、ソルトとパスワードの組み合わせによって異なるハッシュが生成されます。

サーバーに保存する内容は次のようになります

[
    {
        "algorithm": "sha256",
        "username": "jason",
        "salt": "9cb3779f69e271c1",
        "hash": "37a932267ed055facf03cc5d09ca90f927a1eed47a8cd4856e57cd67434426be"
    },
    {
        "algorithm": "sha256",
        "username": "pillboy",
        "salt": "0a19471dab710025",
        "hash": "4be637a8c85455dce0cdc1c7670f062764100276b6ed64141c06fbef4578f185"
    },

]

これらのユーザーに異なるソルトを設定することで、ユーザーが同じパスワードを持っていることを確認できなくなり、攻撃者はハッシュを一般的なパスワードのハッシュについて事前に計算したリストと比較できなくなります。

したがって、bcryptはパスワードハッシュ用に設計されているため、ソルトを使用します。

ゆっくりと

ソルティングは絶対に不可欠ですが、サーバーに保存されているものを自動推測から取得する攻撃者を阻止することはできません。彼女はソルトを取得し、一般的なパスワードと組み合わせて、一致が見つかるまでハッシュを計算できます。彼女は毎秒数千または数億のパスワード推測を実行できる可能性があります。

彼女が非常に多くの推測をすばやく計算できる理由の1つは、sha256のような暗号化ハッシュアルゴリズムが、セキュリティプロパティを満たしながら高速かつ効率的になるように設計されていることです。したがって、bcryptのようなものは「遅いハッシュ」です。アイデアは、あるメッセージ(塩とパスワード)からハッシュに到達するのに非常に多くの計算を必要とするため、通常のコンピューターではハッシュを実行するのに1/4秒かかります。

ユーザーは1/4秒の遅延に気付くことはありませんが、攻撃者が同じ種類のコンピューターを使用している場合、1秒間に1,000万回ではなく4回の推測を行うことになります。 (実際には、彼女は特別に構成されたコンピューティング機器を持っていますが、毎秒数百万回の推測から毎秒数万回の推測に減速することは良いことです。)

bcryptは、いくつかの「遅いハッシュ」の1つです。その他は、PBBKDF2、scrypt、およびArgon2です。最後の2つは、ハッシュを作成するために大量の計算を必要とするだけでなく、大量のメモリも必要とします。

Bcryptは素晴らしいですが...

ソルティングと低速ハッシュは、すべてのパスワードハッシュシステムが行うべきことです。しかし、それはまた収益の減少をもたらします。遅いハッシュが防御側にできることはたくさんあるので、(パスワードが存在する限り)人々がパスワードを推測するのに使用するのを難しくする必要があります。詳細については Bcryptはすばらしいですが... で記述しました

NB:ありがとうございます https://security.stackexchange.com/users/6253/schroeder 文字通り「私は5のように」とった以前の回答を正しく削除していただきありがとうございます。また、元のポスターが役に立たずにいじめられてしまったことをお詫びします。

6