TIL.Bcrypt

4859 ワード

ブログパスワードベースの暗号化ハッシュ関数
Blowfishは鍵方式の対称型ブロック暗号である.
ソフトウェアは良好な暗号化速度を提供しているが、現在、高度な暗号化基準が注目されている.
一方向ハッシュ関数の不足を補うために現れる
単一方向ハッシュ関数の弱点
  • レインボーテーブル攻撃
  • 通常はハッシュ関数を使用して記憶するパスワードから元のパスワードを抽出し、
  • .
  • 無差別対入攻撃(暴力攻撃)
  • ハッシュ関数は、もともと短時間でデータを検索するために設計されていたが、ハッシュ関数の処理速度が速いため、ハッカーは任意の文字列の要約と攻撃する対象の要約を極めて速い速度で比較することができる.
  • ハッシュ関数を使用して変換可能なすべてのハッシュ値を格納
  • MD 5を使用すると、従来の設備を使用して毎秒56億個のダイエット薬を代入することができる.
  • 完全な一方向ハッシュ関数

  • あんぜんきおく
  • パスワードに任意の文字列saltを追加することでサマリーを生成し、同じペンスwordでも異なるsaltを追加して異なるサマリーを生成し、レインボーテーブルを無意味にします.

  • キーストレッチ
  • 海市を何度も繰り返し、時間を増やしてルトフォード攻撃に対応した.
  • パスワードの要約を生成→この要約を入力値として生成する、さらに要約を生成し、
  • を繰り返す.
  • 従来の方法では、毎秒56億個を代入して比較することができ、Kiss Trainingを適用すると、1秒に5回しか比較できないので、Digestを1つ黒くするには長い時間がかかります.
  • bcryptのハッシュ文字列は以下の通りです
    $2b$[cost]$[22 character salt][31 character hash]
    ex)
    $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
     \/ \/ \____________________/\_____________________________/
    Alg Cost       Salt                        Hash
    
    Alg:2 a=ハッシュアルゴリズム識別子(bcrypt)
    Cost : 10 = Cost factor : 2**10 =⇒ 1.024 rounds
    Salt:N 9 qo 8 uLoickx 2 ZMRZoMy=16バイト(128ビット)スロット
    ハッシュ:IjZAgcfl7p92ldGxad68LJZdL17lhWy:24バイトハッシュ

    アルゴリズム#アルゴリズム#

    Function bcrypt
       Input:
          cost:     Number (4..31)                      log2(Iterations). e.g. 12 ==> 212 = 4,096 iterations
          salt:     array of Bytes (16 bytes)           random salt
          password: array of Bytes (1..72 bytes)        UTF-8 encoded password
       Output:
          hash:     array of Bytes (24 bytes)
    
    //Initialize Blowfish state with expensive key setup algorithm
       //P: array of 18 subkeys (UInt32[18])
       //S: Four substitution boxes (S-boxes), S0...S3. Each S-box is 1,024 bytes (UInt32[256])
       P, S ← EksBlowfishSetup(cost, salt, password)
    
    //Repeatedly encrypt the text "OrpheanBeholderScryDoubt" 64 times
       ctext ← "OrpheanBeholderScryDoubt"  //24 bytes ==> three 64-bit blocks
       repeat (64)
          ctext ← EncryptECB(P, S, ctext) //encrypt using standard Blowfish in ECB mode
    
    //24-byte ctext is resulting password hash
       return Concatenate(cost, salt, ctext)

    ハッシュ関数タイプ

  • MD 5、SHA-1、HAS-180:安全なハッシュ関数
  • SHA-256、SHA-512:特定の入力値に対して、常に同じハッシュ値(Rainbowスタックに対して脆弱)
  • を返す.
  • PBKDF 2(Password-Based Key Delivation Function)ハッシュ関数のコンテナPBKDF 2は、ソリューションを適用した後、ハッシュ関数の繰り返し回数を任意に選択することができる.PBKDF 2は非常に軽く実現しやすく,SHAのような検証されたハッシュ関数のみを用いた.(Djangoで使用)
  • 鍵駆動機能bcryptは、最初からパスワード記憶のために設計されている.bcryptはセキュリティ中心で知られるOpenBSDにおいて基本パスワード認証メカニズムとして用いられ,将来的にはPBKDF 2よりも競争力があると考えられる.入力値72バイトの部分はPBKDF 2とcryptと異なる必要があります.
  • 暗号化は比較的新しいアルゴリズムであり、他の2つのアルゴリズムよりも競争力があると考えられているが、まだ拡散していない.cryptは,サマリー生成時にメモリオーバーヘッドを有し,暴力攻撃を試みた場合に並列処理が困難になるように設計されている.そのため、PBKDF 2よりも安全で、将来的にはbcryptよりも競争力があると考えられています.cryptもTarsnapで使用され、セキュリティに非常に敏感なユーザーにバックアップソリューションを提供します.
  • ユーザーインタフェースの注意事項


    パスワード長を制限しない
  • を規制すると、平紋の貯蔵が疑われるだけでなく、暴力の範囲も狭まるため、
  • .
  • の最小長さを制限することが望ましい.
  • 特殊文字の大文字と小文字を問わない
  • のパスワードを入力したPOST要求はSSLで送信する必要があります.
  • パスワードの失敗回数を制限します.
  • 使用方法

    bcrypt.hashpw(パスワード.encode(「utf-8」)、bcrypt。gensalt())


    bcrypt.hashpw(パスワード.encode,gensalt()
    この関数は、パスワードまたは他の任意の文字列をハッシュできます.二つの因子を受ける.
    A string(bytes)
    Salt : bcrypt.ランダム値はgensalt()で自動的に取得できます.

    import bcrypt
    password = '1234'
    hash_password = bcrypt.hashpw(password.encode('utf-8'),bcrypt.gensalt())
    hash_password
    '2a$12acusMujY4QblouspQ.681uJaTU1T.rfsxOalWzUx90yyrV46im.1G'
    サンプル・タイプ
    password = str
    hash_password = str
    qassword.encode(’utf-8’) = byte
    ハッシュ暗号化プロセス
    パスワードを最初のパラメータとして受信し、encodeメソッドのバイトタイプに変更し、gensaltで文字列を追加して暗号化します.
    💡 現在の3.9バージョンでは、decodeを使用しなくても、バイトタイプがstrタイプ=ライブラリに変換される問題がある可能性があります.
    3.9以降では、
    hash_password = bcrypt.hashpw(password.encode('utf-8'),bcrypt.gensalt()).タイプ変換はdecode(「utf-8」)で行う必要があります.
    なぜなら、後でパスワードを比較する過程で、byteタイプではなくstrタイプが比較されるからです.

    bcrypt.checkpw()


    パスワードがデータベースに格納されている値と同じかどうかを確認する関数です.
    b = '1234'
    bcrypt.checkpw(b.encode('utf-8'), hash_password)
    True
    bcrypt.checkpw(b.encode('utf-8'), hash_password)
    True
    d = '12345'
    bcrypt.checkpw(d.encode('utf-8'), hash_password)
    False
    上で実行されている
    import bcrypt
    password = '1234'
    hash_password = bcrypt.hashpw(password.encode('utf-8'),bcrypt.gensalt())
    hash_password
    '2a$12acusMujY4QblouspQ.681uJaTU1T.rfsxOalWzUx90yyrV46im.1G'
    ここでhash passwordにはsalt値があるので、hashpwパラメータでgensalt()を追加的に実行する必要はありません.
    ログイン時に保存したsalt値と一致することを確認するため、passwordの作成時にのみgensaltが使用されます.