Bcrypt

Bcrypt, ve David Mazières tarafından Blowfish şifreleme yöntemi esas alınarak geliştirilmiş ve ilk kez ’te, 1999 yılında sunulmuş bir parola özet fonksiyonudur. saldırılarına karşı kullanmasının yanı sıra adaptif bir fonksiyon olma özelliğine sahiptir. İterasyon sayacı arttırılarak yavaşlatılabilir ve bu sayede karşı dirençli kalabilmektedir.

Bcrypt fonksiyonu OpenBSD’nin varsayılan parola özetleme algoritmasıdır ve SUSE Linux gibi bazı Linux dağıtımlarında da kullanılmaktadır.

Ayrıca, bcrypt’in C, C++, C#, Elixir, Go, Özetin geri kalanı ise maliyet parametresi, 128-bit salt (Radix-64 ile şifrelenmiş 22 karakter) ve 184 bit sonuç özet değeri (Radix-64 ile şifrelenmiş 31 karakter) içerir. Radix-64 unix/crypt alfabesi kullanır ve standart Base-64 değildir. Maliyet parametresi anahtar ilerleme iterasyon sayacı değerini belirtir. 2'nin katları olarak gösterilir ve şifreleme algoritmasının bir girdisidir.

Örneğin gölge parola kaydı $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy maliyet parametresinin 10, yani 210 anahtar ilerleme evresi olduğunu gösterir. Salt ise N9qo8uLOickgx2ZMRZoMye'dir ve sonuç özet değeri ise IjZAgcfl7p92ldGxad68LJZdL17lhWy'dir. Kullanıcının parolası ise standart uygulamada kaydedilmez.

Sürüm geçmişi
$ 2 $ (1999)

Orijinal Bcrypt tanımlarına göre ön ek olarak $2$ kullanılır. Bu tanımlara göre OpenBSD şifre dosyalarında parolaların kaydedilmesinde Modular CryptFormat takip edilir.

$1$ : MD5 tabanlı şifreleme ('md5crypt')
$2$ : Balon balığı tabanlı şifreleme ('bcrypt')
$sha1$ : SHA-1 tabanlı şifreleme ('sha1crypt')
$5$ : SHA-256 tabanlı şifreleme ('sha256crypt')
$6$ : SHA-512 tabanlı şifreleme ('sha512crypt')

$ 2a $

Orijinal tanımlarda non-ASCII karakterlerin veya sıfır sonlayıcıların nasıl değerlendirileceği belirtilmemiştir. Tanımlar aşağıdaki yönergeler dahil edilecek şekilde revize edilmiştir:

String UTF-8'e göre kodlanmış olmalıdır
null terminator dahil edilmelidir

Bu değişikliklerle birlikte versiyon $2a$ olarak değiştirilmiştir

$ 2x $, $ 2y $ (Haziran 2011)

Haziran 2011'de BCrypt'in bir PHP uygulaması olan crypt_blowfish’te bir hata keşfedildi. Bu, 8. bit setindeki karakterlerin yanlış değerlendirilmesiyle alakalı bir hataydı. Sistem yöneticilerinin ellerindeki mevcut parola veri tabanlarını $2a$ 'dan $2x$'e geçerek güncellemeleri önerildi. Aynı zamanda crypt_blowfish’in sabit algoritmalarla üretilen özetler için $2y$'yi yayınlaması fikri de ortaya atıldı.

Kanonik OpenBSD de dahil olmak üzere kimse 2x/2y fikrini benimsemedi. Bu versiyon yalnızca crypt_blowfish ile sınırlı kaldı.

$ 2b $ (Şubat 2014)

Bcrypt’in OpenBSD uygulamasında bir hata tespit edildi. String uzunlukları unsigned char (i.e. 8 bit Byte) olarak tutuluyordu. Eğer parola 255 karakterden uzunsa taşma meydana geldiği ve 255’te sınırlandığı görüldü.

BCrypt OpenBSD için oluşturulduğu için, bu kütüphanedeki hatadan sonra versiyon numarasının yükseltilmesine karar verildi.

Algoritma
Bcrypt algoritması “OrpheanBeholderScryDoubt” metninin Blowfish kullanılarak 64 defa şifrelenmesinin sonucudur. Bcrypt’te standart Blowfish anahtar hazırlama fonksiyonu, daha yavaş anahtar hazırlama fonksiyonuyla (EksBlowfishSetup) değiştirilmiştir:
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
state EksBlowfishSetup(cost, salt, password)

//Repeatedly encrypt the text "OrpheanBeholderScryDoubt" 64 times
ctext "OrpheanBeholderScryDoubt" //24 bytes ==> three 64-bit blocks
repeat (64)
ctext EncryptECB(state, ctext) //encrypt using standard Blowfish in ECB mode

//24-byte ctext is resulting password hash
return Concatenate(cost, salt, ctext)

Maliyetli anahtar oluşturma
Bcrypt algoritması aşağıdaki mantıkta çalışan “Eksblowfish” anahtar hazırlama algoritmasına bağlıdır:

Function EksBlowfishSetup
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:
state: opaque BlowFish state structure

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

return state

Expand Key
ExpandKey fonksiyonu aşağıdaki işlemleri yapar:

Function ExpandKey(state, salt, password)
Input:
state: Opaque BlowFish state structure Internally contains P-array and S-box entries
salt: array of Bytes (16 bytes) random salt
password: array of Bytes (1..72 bytes) UTF-8 encoded password
Output:
state: opaque BlowFish state structure

//Mix password into the internal P-array of state
for n 1 to 18 do
Pn Pn xor password[32(n-1)..32n-1] //treat the password as cyclic

//Encrypt state using the lower 8 bytes of salt, and store the 8 byte result in P1|P2
block Encrypt(state, salt[0..63])
P1 block[0..31] //lower 32-bits
P2 block[32..63] //upper 32-bits

//Continue encrypting state with salt, and storing results in remaining P-array
for n 2 to 9 do
block Encrypt(state, block xor salt[64(n-1)..64n-1]) //encrypt using the current key schedule and treat the salt as cyclic
P2n-1 block[0..31] //lower 32-bits
P2n block[32..63] //upper 32-bits

//Mix encrypted state into the internal S-boxes of state
for i 1 to 4 do
for n 0 to 127 do
block Encrypt(state, block xor salt[64(n-1)..64n-1]) //as above
Si[2n] block[0..31] //lower 32-bits
Si[2n+1] block[32..63] //upper 32-bits
return state

Böylelikle, tüm XOR'lar ve sıfır salt değerleri etkisiz olduğu için ExpandKey(state, 0, key) standart Blowfish anahtar zamanlamasıyla aynıdır. ExpandKey(state, 0, salt) için de benzer şeyler söylenebilir, fakat bu fonksiyon salt değerini 128 bit anahtar olarak kullanır.

Kullanıcı girdisi
Bcrypt'in birçok uygulaması OpenBSD'de olduğu gibi parolayı ilk 72 baytı kalacak şekilde kırpar.

Matematiksel algoritma ise 18 adet 32 bit alt anahtar ile (72 octet/byte'a eşdeğer) başlamaya hazır hale gelir. Bcrypt'in orijinal tanımlarında metin tabanlı şifreleri userland’den nümerik değerlere eşleştirmek için önerilen belirli bir metod yoktur. Metinde geçen kısa bir yorum string karakterlerini ASCII olarak şifreleyerek tutmaktan (zorunlu tutmaksızın) bahseder ve şöyle devam eder: “Sonuç olarak, buradaki anahtar argümanı, kullanıcı tarafından seçilen 56 byte’tan küçük(eğer anahtar ASCII string’i ise sonuçlandırma sıfır byte’ı da dahil olmak kaydıyla) bir gizli şifreleme anahtarıdır.

Bcrypt'in farklı uygulamaları birbirinden, parolaları nümerik değerlere ilk dönüştürmelerinde kullandıkları yöntem farklılıklarıyla ayrışmıştır.

Ayrıca bakınız
bcrypt aynı zamanda, 2002'de Blowfish tarafından geliştirilen cross-platform dosya şifreleme sistemi aracının da adıdır.
Argon2 (2015'te Pasword Hashing Competition'ın kazananı)
Crypt (C)#Blowfish tabanlı şema şifreleme – şifre saklama ve doğrulama şeması – Blowfish
Key stretching
PBKDF2 (Parola Tabanlı Anahtar Türetme İşlevi 2)
scrypt

Kaynakça
Dış bağlantılar
crypt_blowfish, Openwall tarafından sağlanan uygulama