Bir Bcrypt karma parolasını bir Veritabanında depolamak için hangi sütun türünü / uzunluğunu kullanmalıyım?


318

Karma bir parolayı (BCrypt kullanarak) bir veritabanında saklamak istiyorum. Bunun için iyi bir tip ne olabilir ve hangisi doğru uzunluk olurdu? BCrypt ile şifreleri her zaman aynı uzunlukta midir?

DÜZENLE

Örnek karma:

$2a$10$KssILxWNR6k62B7yiX0GAe2Q7wwHlrzhF3LqtVvpyvHZf0MwvNfVu

Bazı şifreleri karıştırdıktan sonra, BCrypt her zaman 60 karakter karması üretir.

DÜZENLEME 2

Uygulamadan bahsetmediğim için üzgünüm. JBCrypt kullanıyorum .


Ayrıca Openwall'un PHP şifre karma çerçevesine (PHPass) bakın. Taşınabilir ve kullanıcı şifreleri üzerinde yaygın saldırılara karşı sertleştirilmiş. Çerçeveyi yazan kişi (SolarDesigner) John The Ripper'ı yazan ve Password Hashing Yarışması'nda yargıç olarak oturan aynı adamdır . Bu yüzden parola saldırıları hakkında bir iki şey biliyor.
jww

1
Herkes için bir çözüm arayan bu denk gelirse scrypt : Gumbo cevabı da scrypt için de geçerlidir. Kişisel olarak MySQL'de BINARY (64) uyguladım ve daha sonra Python altında bayt eşitliğini test etmeme izin verdi.
Philippe Hebert

Yanıtlar:


369

Bcrypt için modüler crypt biçimi şunlardan oluşur:

  • $2$, $2a$Ya da $2y$tanımlama müzakere algoritmasının ve biçimini
  • maliyet parametresini gösteren iki basamaklı bir değer ve ardından $
  • 53 karakter uzunluğunda bir değer baz-64 kodlu (bunlar alfabe kullanmak ., /, 0- 9, A- Z, a- zfarklı olduğunu standart Base 64 kodlama alfabesi) oluşan:
    • 22 karakter tuz (etkin bir şekilde 132 kod çözülmüş bitin sadece 128 biti)
    • 31 karakter şifreli çıktı (186 adet kod çözülmüş bitin sadece 184 biti)

Böylece toplam uzunluk sırasıyla 59 veya 60 bayttır.

2a biçimini kullandıkça 60 bayta ihtiyacınız olacaktır. Ve böylece MySQL için CHAR(60) BINARYveyaBINARY(60) ( kullanmanızı öneririz . _Bin ve binary Collations arasındaki fark hakkında bilgi).

CHARikili güvende değildir ve eşitlik yalnızca bayt değerine değil, gerçek harmanlamaya da bağlıdır; en kötü durumda Aeşit kabul edilir a. Bkz ve harmanlamalar fazla bilgi için._binbinary


28
Dikkatli olun - ikili (60) olarak saklamak string eşitliği için beklenmedik davranışlara neden olabilir (diğer şeylerin yanı sıra). .NET'te bu String.Equals (fromDataBaseBinary60string, typicalishString, StringComparison.InvariantCulture)
JHubbard80

8
Sütunu CHAR (60) CHARACTER SET latin1 COLLATE latin1_bin olarak tanımlarsanız, artık ikili bir sütuna ihtiyaç duymadan doğru dize karşılaştırmasının avantajlarını elde edersiniz.
Ben

2
@AndreFigueiredo MySQL'de SQL_Latin1_General_CP1_CS_ASbilinmiyor. Bilinen nedir latin1_general_cs.
Gumbo

1
Burada bir tanımı var isteriz neyi 2, 2ave 2ykarma algoritması ve biçimi için ortalama. Bazı aramalarda kolay bir cevap veremedim.
jocull

2
@Neon Sorun, farklı karmaları eşit olarak karşılaştırabilmenizdir. Açıkça bir ikili sütun (veya doğru harmanlama ile bir VARCHAR) belirtirseniz, başka bir yerde, büyük / küçük harfe duyarlı olmayan bir karşılaştırma yapan bazı ayarları değiştirme riskiyle karşılaşmazsınız. Ayrıca niyetinizi daha açık hale getirir, bu genellikle iyi bir şeydir - ikili verileri saklıyorsunuz; ikili veri olarak saklamalısınız.
Monica'nın Davası

52

Bir Bcrypt karması bir BINARY(40)sütunda saklanabilir .

BINARY(60), diğer cevapların önerdiği gibi, en kolay ve en doğal seçimdir, ancak depolama verimliliğini en üst düzeye çıkarmak istiyorsanız, hash'ı kayıpsız şekilde yapılandırarak 20 bayt tasarruf edebilirsiniz. Bunu GitHub'da daha ayrıntılı olarak belgeledim: https://github.com/ademarre/binary-mcf

Bcrypt karmaları, modüler crypt formatı (MCF) olarak adlandırılan bir yapıyı takip eder. İkili MCF (BMCF) bu metin karması temsillerini daha kompakt bir ikili yapıya şifreler. Bcrypt söz konusu olduğunda, sonuçta elde edilen ikili karma 40 bayttır.

Gumbo, bir Bcrypt MCF karma işleminin dört bileşenini açıklamak için iyi bir iş çıkardı:

$<id>$<cost>$<salt><digest>

BMCF'ye kod çözme şu şekildedir:

  1. $<id>$ 3 bit ile temsil edilebilir.
  2. <cost>$04-31, 5 bit halinde temsil edilebilir. Bunları 1 bayt için bir araya getirin.
  3. 22 karakterlik tuz, 128 bitlik (standart olmayan) bir baz-64 temsilidir. Base-64 kod çözme 16 bayt verir.
  4. 31 karakterlik karma özet 23 bayta kodlanmış baz-64 olabilir.
  5. Hepsini 40 bayt için bir araya getirin: 1 + 16 + 23

GitHub'da yukarıdaki bağlantıdan daha fazla bilgi edinebilir veya PHP uygulamamı inceleyebilirsiniz .


49
Daha uzun alan maliyeti: Milyonlarca kayıt bile 20 bayt + kayıtlar: Milyonlarca kayıt + 'ya ulaştığınızda 20MB. Çok karmaşık bir güvenlik ve mühendislik alanında, kısaltılmış bir alan uzunluğunun yanlış uygulanmasının maliyeti: $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ $$$$$$$$$$$$$$$$$$$$$$$$$$$$ Sen matematik.
Kzqai

6
@Kzqai, dediğim gibi, daha büyük 60 baytlık sütun en doğal seçimdir, ancak depolama verimliliğini takip etmenin ne kadar agresif bir şekilde projeye bağlıdır. Örneğin, tüm veritabanını belleğe sığdırmaya çalışmak yaygındır ve burada 20 MB ve başka bir 20 bellek kısıtlı bir ortamda hızlı bir şekilde toplanabilir.
Andre D

10
Örneğim benim açımdan. --- Veritabanınızı belleğe koymak istiyorsanız, bcrypt saklama sütununa dokunmadan önce diğer tüm sütunları optimize edin. --- Diğer tüm sütunları deli derecelere kadar optimize ettiyseniz ve yalnızca bcrypt karma sütunu kaldıysa, sadece bcrypt için başka bir bellek parçası alın. --- Yukarıdakilerin her ikisini de yaptıysanız ... ... durun, düşük asılı meyvelerin diğer sütunlarını optimize etmediniz ve çalışan ve değiştirilen test edilmiş bir şifreleme güvenlik sistemi ile uğraşmak üzeresiniz. daha karmaşık bir evde yetiştirilen sistem ile uygulama başarısızlığı şansı.
Kzqai

11
@Kzqai Burada Bcrypt kütüphanenizin güvenliğini zayıflatma riski yoktur. Parola kontrolünden önce depolama alanından alındığında geri alınan bir veri kodlamasıdır. Bu "kendi kripto parasını yuvarlama" bölgesi değil.
Andre D

1
Güzel açıklama. :) Açıklamanız harika bir fikir vermesine rağmen, sadece güvenli tarafta olmak için 60 karakter, hatta 100 karakter ile gitmek istiyorum. Güzel tartışmalar da @Kzqai ve AndreD
Naveen Kumar V

23

Eğer bcrypt hash (ki bu soruyu okuyan insanların büyük bir yüzdesi olduğunu varsayalım) oluşturmak password_hash()için PASSWORD_DEFAULTalgoritma ile PHP kullanıyorsanız , gelecekte password_hash()varsayılan olarak farklı bir algoritma kullanabileceğinizi ve bu nedenle olabilir unutmayın karma uzunluğunu etkiler (ancak mutlaka daha uzun olmayabilir).

Kılavuz sayfasından:

PHP'ye yeni ve daha güçlü algoritmalar eklendikçe bu sabitin zamanla değişecek şekilde tasarlandığını unutmayın. Bu nedenle, bu tanımlayıcıyı kullanarak sonucun uzunluğu zaman içinde değişebilir. Bu nedenle, sonucun 60 karakterden fazla genişleyebilecek bir veritabanı sütununda saklanması önerilir (255 karakter iyi bir seçim olacaktır).

255 baytlık parola karmaları depolamak için 1 milyar kullanıcınız (yani şu anda facebook ile rekabet ediyor olsanız bile) bcrypt'i kullanmak, ufacık bir SSD sabit sürücünün boyutu hakkında sadece ~ 255 GB veri olacaktır. Şifre karmasının saklanmasının uygulamanızdaki darboğaz olması son derece düşük bir olasılıktır. Ancak depolama alanı gerçekten bu off şansı olan nedense bir sorun kullanabilirsiniz PASSWORD_BCRYPTkuvvete password_hash()varsayılan olmasa bile, kullanım Bcrypt için. Bcrypt'te bulunan güvenlik açıkları hakkında bilgi sahibi olduğunuzdan ve yeni bir PHP sürümü her yayınlandığında sürüm notlarını gözden geçirdiğinizden emin olun. Varsayılan algoritma hiç değiştirilmezse, nedenini gözden geçirmek ve yeni algoritmayı kullanıp kullanmama konusunda bilinçli bir karar vermek iyi olur.


20

Örneğin MD5 karma ile yapabileceğiniz gibi bunu saklayabileceğiniz düzgün hileler olduğunu düşünmüyorum.

Bence en iyi seçim CHAR(60)her zaman 60 karakter uzunluğunda olduğu gibi


Her ne kadar, PHP belgeleri sütunların gelecekteki sürümler için daha fazla veri tutabilmesi gerektiğini belirtiyor ...
Julian F. Weinert

16
Altın plakaya sebep yok. Kullandığınız yazılım altmış bayt gerektiriyorsa, altmış bayt ayırın. Yazılımınızın gelecekte bunu değiştirecek bir sürümü varsa, bu sürüm gerçekleştiğinde endişelenebilirsiniz. İşlev değiştiren güncelleştirmeleri otomatik olarak yüklememelisiniz.
Tyler Crompton
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.