バイクリプトステップバイステップ
18502 ワード
郵便Bcrypt Step by Step 初登場Qvault .
bcryptはaであるkey derivation function , これは遅いと考えられるhash function . その目的は、ゆっくりと一定のサイズ、決定論的、予測不可能な出力に入力データの一部を変換することです.一般的なユースケースは、パスワードをNビット暗号化キーに変換することです.
ヒアアットQvault, 我々は、セキュリティシステムでbcryptを使用します.bcryptは非常に人気のあるパスワードハッシュ機能ですので、現在のところ我々の実装を教えるハッシュ関数ですPractical Cryptography コース.
bcryptのように見えます
mypassword 123でbcryptを使用すると次のようになります.
**_myPassword123_** ->$2y$12$vUw4OU4EAl4w4vC6/lA33OtDSYGhiIdekdT9iOoSs9/ckwrffaEui
この出力を使用すると、将来のハッシュに対して、元のデータが一致するかどうかを比較できます.なぜ直接パスワードを比較しない?
Web開発では、ユーザのパスワードをプレーンテキストに保存するのは安全です.攻撃者がサーバーのデータベースへのアクセスを得るなら、彼らは生の電子メール/パスワード組合せを見つけることができて、彼らを他のサイトで同じユーザーを攻撃するために使うことができました.
少なくとも、ユーザのパスワードをハッシュする必要がありますが、ハッシュ関数SHA-2 そして、MD 5はあまりに速く、安全であるためにあります.KDFのようなBcryptを使用すると、それは計算的に高価で遅いため、高速ハッシュのセキュリティ上の利点を提供します.攻撃者が速いアルゴリズムで作られるパスワードハッシュのデータベースへのアクセスを得るならば、彼らが異なる入力を推測して、出力がマッチするかどうか見ることによってハッシュを「逆」にするのは簡単です.
たとえば、攻撃者がデータベースに次のエントリを見つけたとしましょう.
[email protected] 5906ac361a137e2d286465cd6588ebb5ac3f5ae955001100bc41577c3d751764
以下のような一般的なパスワードをハッシュしてみることができます.password1 ->0b14d501a594442a01c6859541bcb3e8164d183d32937b851835442f69d5c94epassword2 ->6cf615d5bcaac778352a8f1f3360d23f02f34ec182e259897fd6ce485d7870d4password3 -> 5906ac361a137e2d286465cd6588ebb5ac3f5ae955001100bc41577c3d751764
パスワードpassword3
, 一致するハッシュを生産!今攻撃者は知っている[email protected]
はパスワードを使用しますpassword3
他のサイトで、他のアカウントをハック行くことができます.攻撃者がすぐに多くのハッシュを計算することができるので、これは可能です.遅いkdfのようなbcryptはこの問題を解決します.
bcrypt出力形式
$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy\_\_\_/\_\_/\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_/\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_/Alg Cost Salt Hash
2a
: hashアルゴリズムの識別子( bcrypt )10
: コストファクター10
= 1024ラウンド展開N9qo8uLOickgx2ZMRZoMye
: 16バイト( 128ビット)塩、22文字にエンコードされたbase 64IjZAgcfl7p92ldGxad68LJZdL17lhWy
: 24バイト( 192ビット)ハッシュbcryptは一歩一歩説明した
bcryptは次のような擬似コードで可視化できます:
func bcrypt(cost int, salt [16]byte, password [72]byte) (hash string) {
// Initialize Blowfish state with expensive key setup algorithm
// This is the slow part of the algorithm
pEighteenSubkeys, sFourSubBoxes := expensiveBlowfishSetup(cost, salt, password)
// Repeatedly encrypt the text "OrpheanBeholderScryDoubt" 64 times
// 24 bytes = three 64-bit blocks
ctext := "OrpheanBeholderScryDoubt"
for i := 0; i < 64; i++ {
// Encrypt using standard Blowfish in ECB mode
ctext = encryptECB(pEighteenSubkeys, sFourSubBoxes, ctext)
}
// return the version, cost, salt, and ctext in the proper format
return "$2a${cost}${salt}{ctext}"
}
ご覧のように、BcryptはBlowfish 暗号.簡単に言えば、BcryptはBlowfish暗号化と組み合わせる高価なキー拡張です.The
expensiveBlowfishSetup
関数は擬似コードに従って理解できる:// pEighteenSubkeys: array of 18 subkeys
// sFourSubBoxes: Four substitution boxes
// Each S-Box is a 256-length array of uint32
func expensiveBlowfishSetup(cost int, salt [16]byte, password [72]byte) (pEighteenSubkeys [18]uint32, sFourSubBoxes [4][256]uint32) {
// Initialize arrays
pEighteenSubkeys := [18]uint32
sFourSubBoxes := [4][256]uint32
// Fill pEighteenSubkeys and sFourSubBoxes with the hex digits of pi
// This initial state works as in the original Blowfish algorithm
// it populates the P-array and S-box entries with the fractional part of pi in hexadecimal
pEighteenSubkeys = fillWithPi(pEighteenSubkeys)
sFourSubBoxes = fillWithPi(sFourSubBoxes)
// Permutate P and S based on the password and salt
pEighteenSubkeys, sFourSubBoxes = expandKey(pEighteenSubkeys, sFourSubBoxes, salt, password)
// This is the "Expensive" part of the "Expensive Key Setup"
// Otherwise the key setup would be identical to Blowfish
// Expand the key an exponentially increasing number of times
// depending on the cost factor
for i := 0; i < math.Pow(2, cost); i++ {
pEighteenSubkeys, sFourSubBoxes = expandKey(pEighteenSubkeys, sFourSubBoxes, 0, password)
pEighteenSubkeys, sFourSubBoxes = expandKey(pEighteenSubkeys, sFourSubBoxes, 0, salt)
}
return pEighteenSubkeys, sFourSubBoxes
}
The expandKey function
は、cost
パラメータThe expandKey
関数は以下の擬似コードで説明する:func expandKey(pEighteenSubkeys [18]uint32, sFourSubBoxes [4][256]uint32, salt [16]byte, password [72]byte) (
pEighteenSubkeys [18]uint32, sFourSubBoxes [4][256]uint32
) {
// Mix password into the pEighteenSubkeys array
// by XORing password with subkeys
for i := 0; i < 18; i++{
// treat the password as cyclic, XOR 32 bit chunks of password with subkeys
pEighteenSubkeys[i] ^= password[i % 18]
}
// Treat the 128-bit salt as two 64-bit halves
saltHalf[0] = salt[0:63]
saltHalf[1] = salt[64:127]
// Initialize an 8-byte (64-bit) buffer with all zeros.
block := [8]byte
// Mix internal state into P-boxes
for i := 0; i < 9; i++ {
// XOR 64-bit block with a 64-bit salt half
// Each iteration alternating between saltHalf[0], and saltHalf[1]
block ^= saltHalf[(i-1) mod 2]
// Encrypt block using current key schedule with blowfish block encryption
block = Encrypt(pEighteenSubkeys, sFourSubBoxes, block)
// Split block and use as new subkeys
pEighteenSubkeys[2*i] = block[0:31]
pEighteenSubkeys[2*i + 1] = block[32:63]
}
// Mix encrypted state into the internal S-boxes of state
for i := 0; i < 4; i ++ {
for j := 0; j < 127; j++ {
// Encrypt block using blowfish block encryption
// where salt[i] is 64 bit chunks
block = Encrypt(pEighteenSubkeys, sFourSubBoxes, block ^ salt[i])
sFourSubBoxes[2*i] = block[0:31]
sFourSubBoxes[2*i + 1] = block[32:63]
}
}
return pEighteenSubkeys, sFourSubBoxes
}
goのようなもっとリアルなプログラミング構文を使って疑似コードの詳細を視覚化するのに役立ちます.それがあなたを助けないならばWikipedia ここのページ.読書ありがとう!
あなたがどんな質問またはコメントをするならば、さえずりの上で我々について来てください
コーディングコースのようなゲームを取るQvault Classroom
Subscribe より多くの教育記事のための我々の会報へ
Reference
この問題について(バイクリプトステップバイステップ), 我々は、より多くの情報をここで見つけました https://dev.to/wagslane/bcrypt-step-by-step-1fmpテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol