En İyi Uygulamalar: Şifreleri tuzlama ve biberleme?


154

Yaptığım şeyin aslında şifreleri tuzlamaktan ziyade onları biberleştirmek olduğunu öğrendiğim bir tartışmaya rastladım ve o zamandan beri her ikisini de şu şekilde yapmaya başladım:

hash_function($salt.hash_function($pepper.$password)) [multiple iterations]

Seçilen hash algoritmasını görmezden gelmek (Bunun tuzlar ve biberlerin bir tartışması olmasını istiyorum ve belirli algoritmalar değil, güvenli bir tane kullanıyorum), bu güvenli bir seçenek mi yoksa farklı bir şey mi yapmalıyım? Terimlere aşina olmayanlar için:

  • Bir tuz , şifreleri kırmak için karma tabloların kullanılmasını imkansız hale getirmek üzere tasarlanmış veritabanında genellikle dizeyle depolanan rastgele oluşturulmuş bir değerdir. Her şifrenin kendi tuzu olduğundan, şifreleri kırmak için tek tek kaba kuvvet uygulanmalıdır; ancak, tuz veri tabanında parola karması ile saklandığından, veri tabanı uzlaşması her ikisini de kaybetmek anlamına gelir.

  • Bir biber gizli olması amaçlanmıştır (genellikle uygulamanın kaynak kodunda kodlanmış) veri tabanında ayrı olarak depolanır site çapında bir statik bir değerdir. Veritabanından bir uzlaşmanın tüm uygulamanın parola tablosunun kaba kuvvet uygulanmasına neden olmaması için kullanılır.

Eksik bir şey var mı ve parolalarımı tuzlamak ve karabiber yapmak, kullanıcımın güvenliğini korumak için en iyi seçenek mi? Bunu bu şekilde yapmanın herhangi bir potansiyel güvenlik kusuru var mı?

Not: Uygulama ve veri tabanının ayrı makinelerde depolandığını, şifreleri paylaşmadığını, bu nedenle veri tabanı sunucusunun ihlali, uygulama sunucusunun otomatik olarak ihlal edildiği anlamına gelmez.


3
Değil oldukça yinelenen ama son derece ilişkili: stackoverflow.com/questions/16594613/...
ircmaxell

Yanıtlar:


316

Tamam. Bu konuda yazma gerektiğinden gören over ve üzerinde , yalnız biber son bir kanonik cevap yapacağız.

Biberlerin Görünen Upside

Biberlerin haşhaş fonksiyonlarını daha güvenli hale getirmesi gerektiği çok açık görünüyor. Demek istediğim, saldırgan yalnızca veritabanınızı ele geçirirse, kullanıcılarınızın parolaları güvende olmalıdır, değil mi? Mantıklı görünüyor, değil mi?

Bu yüzden pek çok insan biberin iyi bir fikir olduğuna inanıyor. Mantıklı".

Biberler Gerçeği

Güvenlik ve kriptografi alanlarında, "mantıklı olmak" yeterli değildir. Bir şeyin güvenli kabul edilmesi için kanıtlanabilir ve mantıklı olması gerekir. Ek olarak, sürdürülebilir bir şekilde uygulanabilmelidir. Sürdürülemeyen en güvenli sistemin güvensiz olduğu kabul edilir (çünkü bu güvenliğin herhangi bir parçası bozulursa, tüm sistem dağılır).

Ve biber ne kanıtlanabilir ne de bakımı yapılabilir modellere uyuyor ...

Biberlerle İlgili Teorik Sorunlar

Şimdi sahneyi kurduğumuza göre, gelin biberde neyin yanlış olduğuna bakalım.

  • Bir hash'i diğeriyle beslemek tehlikeli olabilir.

    Örneğinizde yaparsınız hash_function($salt . hash_function($pepper . $password)).

    Geçmiş deneyimlerimizden bir hash sonucunu başka bir hash fonksiyonuna "sadece beslemenin" genel güvenliği azaltabileceğini biliyoruz. Bunun nedeni, her iki hash işlevinin de saldırı hedefi haline gelebilmesidir.

    Bu nedenle PBKDF2 gibi algoritmalar , bunları birleştirmek için özel işlemler kullanır (bu durumda hmac).

    Mesele şu ki, önemli bir şey olmasa da, etrafta dolaşmak da önemsiz bir şey değil. Kripto sistemleri, "çalışmalı" durumlarından kaçınmak ve bunun yerine "çalışmak için tasarlanmış" durumlara odaklanmak üzere tasarlanmıştır.

    Bu tamamen teorik görünse de aslında değil. Örneğin, Bcrypt rastgele parolaları kabul edemez . Yani geçen bcrypt(hash(pw), salt)çok daha zayıf karma gerçekten de neden olabilir bcrypt(pw, salt)eğer hash()getiri ikili dize.

  • Tasarıma Karşı Çalışmak

    Bcrypt'in (ve diğer parola karma algoritmalarının) tasarlanma şekli bir tuzla çalışmaktır. Biber kavramı asla tanıtılmadı. Bu bir önemsiz gibi görünebilir, ama değil. Nedeni, tuzun sır olmamasıdır. Bir saldırganın bildiği bir değerdir. Öte yandan bir biber, tanımı gereği kriptografik bir sırdır.

    Mevcut parola karma algoritmalarının (bcrypt, pbkdf2, vb.) Tümü yalnızca bir gizli değeri (parola) alacak şekilde tasarlanmıştır. Algoritmaya başka bir sır eklemek hiç çalışılmadı.

    Bu güvenli olmadığı anlamına gelmez. Güvenli olup olmadığını bilmediğimiz anlamına gelir. Ve güvenlik ve kriptografi ile ilgili genel öneri, eğer bilmiyorsak öyle değildir.

    Bu nedenle, algoritmalar şifreleme uzmanları tarafından gizli değerlerle (biber) kullanılmak üzere tasarlanıp incelenene kadar, mevcut algoritmalar onlarla birlikte kullanılmamalıdır.

  • Karmaşıklık Güvenliğin Düşmanıdır

    İster inanın ister inanmayın, Karmaşıklık Güvenliğin Düşmanıdır . Karmaşık görünen bir algoritma yapmak güvenli olabilir veya olmayabilir. Ancak güvenli olmaması ihtimali oldukça önemli.

Biberlerle İlgili Önemli Sorunlar

  • Sürdürülebilir Değil

    Biber uygulamanız, biber anahtarının döndürülmesini engeller. Biber tek yön fonksiyonunun girişinde kullanıldığından, değerin ömrü boyunca asla biberi değiştiremezsiniz. Bu, anahtar rotasyonunu desteklemesi için bazı sakat hackler bulmanız gerektiği anlamına gelir.

    Bu, kriptografik sırları her sakladığınızda gerekli olduğu için son derece önemlidir. Anahtarları döndürmek için bir mekanizmaya sahip olmamak (periyodik olarak ve bir ihlalden sonra) büyük bir güvenlik açığıdır.

    Ve mevcut biber yaklaşımınız, her kullanıcının şifresinin bir rotasyonla tamamen geçersiz kılınmasını veya dönüşümlü olarak bir sonraki girişlerine kadar beklemesini gerektirecektir (ki bu asla olmayabilir) ...

    Bu da temelde yaklaşımınızı hemen yapılmaz hale getirir.

  • Kendi Kripto'nuzu Yuvarlamanızı Gerektirir

    Hiçbir geçerli algoritma biber kavramını desteklemediğinden, bir biberi desteklemek için ya algoritmalar oluşturmanızı ya da yenilerini icat etmenizi gerektirir. Ve bunun neden gerçekten kötü bir şey olduğunu hemen anlayamazsanız:

    En beceriksiz amatörden en iyi kriptografa kadar herkes kendi kıramayacağı bir algoritma yaratabilir.

    ASLA kendi kriptoyu devir ...

Daha İyi Yol

Dolayısıyla, yukarıda detaylandırılan tüm sorunlardan durumu ele almanın iki yolu vardır.

  • Algoritmaları Var Olduğu Gibi Kullanın

    Eğer bcrypt veya scrypt'i doğru kullanırsanız (yüksek bir maliyetle), en zayıf sözlük şifreleri dışında tümü istatistiksel olarak güvenli olmalıdır. 5 maliyetle bcrypt karma oluşturma için mevcut kayıt saniyede 71k karmadır. Bu durumda 6 karakterli rastgele bir şifrenin bile kırılması yıllar alır. Ve benim minimum tavsiye edilen maliyetimin 10 olduğu düşünülürse, bu da saniyede hash sayısını 32 kat azaltıyor. Yani saniyede sadece 2200 hash'den bahsediyor oluruz. Bu hızda, bazı sözlük cümleleri veya modifikasyonları bile güvenli olabilir.

    Ek olarak, kapıda bu zayıf şifre sınıflarını kontrol etmeliyiz ve içeri girmelerine izin vermemeliyiz. Şifre kırma geliştikçe, şifre kalite gereksinimleri de artmalıdır. Hala istatistiksel bir oyundur, ancak uygun bir depolama tekniği ve güçlü şifrelerle, herkes pratik olarak çok güvende olmalıdır ...

  • Depolamadan Önce Çıktı Özetini Şifrele

    Güvenlik alanında, yukarıda söylediğimiz her şeyin üstesinden gelmek için tasarlanmış bir algoritma vardır. Bu bir blok şifreleme. İyi, çünkü tersine çevrilebilir, böylece tuşları döndürebiliriz (yaşasın! Bakım kolaylığı!). İyi çünkü tasarlandığı gibi kullanılıyor. Bu iyidir çünkü kullanıcıya hiçbir bilgi vermez.

    O satıra tekrar bakalım. Bir saldırganın algoritmanızı bildiğini varsayalım (bu güvenlik için gereklidir, aksi takdirde belirsizlik yoluyla güvenliktir). Geleneksel biber yaklaşımı ile saldırgan bir nöbetçi şifresi oluşturabilir ve tuzu ve çıkışı bildiği için biberi kaba kuvvetle zorlayabilir. Tamam, bu uzun bir atış, ama mümkün. Bir şifre ile saldırgan hiçbir şey almaz. Ve tuz rastgele hale getirildiği için, nöbetçi bir şifre ona yardımcı bile olmayacak. Bu yüzden bıraktıkları en iyi şey şifreli forma saldırmaktır. Bu, şifreleme anahtarını kurtarmak için önce şifrelenmiş karmanıza saldırmaları ve ardından karmalara saldırmaları gerektiği anlamına gelir. Ancak şifrelere saldırmakla ilgili çok fazla araştırma var, bu yüzden buna güvenmek istiyoruz.

TL / DR

Biber kullanma. Bunlarla ilgili bir dizi sorun var ve daha iyi iki yol var: herhangi bir sunucu tarafı gizli bilgisi kullanmamak (evet, sorun değil) ve depolamadan önce bir blok şifresi kullanarak çıktı karmasını şifrelemek.


6
Karma değerini şifrelemenin bu son bölümünü eklediğiniz için teşekkürler, bu tamamen kabul edebileceğim bir cevap. Şifreleme, parola api'nizin bir parçası olursa, onu kullanmamanız için hiçbir neden olmazdı, bu yüzden belki ... (bunun için belgeleri yazmak
isterim

2
@martinstoeckli: Şifreleme adımını basitleştirilmiş hashing API'sine eklemeyi kabul etmem. Nedeni, sırların (anahtarların) saklanmasının insanların fark ettiğinden çok daha zor olması ve kendinizi ayağınızdan vurmanın oldukça kolay olmasıdır. Dışarıdaki kullanıcıların% 99.9'u için, ham bcrypt en basit şifreler dışında hepsi için fazlasıyla yeterli ...
ircmaxell

7
@ircmaxell - Diğer tarafta, hiçbir şey kaybetmezsiniz. En kötü durumda, anahtar bilindiğinde, saldırganın BCrypt karmasını kırması gerekir (şifrelemesiz ile aynı durum). Bu, verileri şifrelemek için bir anahtar depolamakla aynı şey değildir, bu, sunucu tarafı bir sır eklemekle ilgilidir. Saldırganın sunucu / kod üzerinde kontrolü olmadığı sürece, sabit kodlanmış bir anahtar bile bu zayıf parolaları koruyabilir. Bu durum nadir değildir: SQL enjeksiyonunun yanı sıra, yedeklerin atılması, atılan sunucular… bu duruma yol açabilir. Pek çok PHP kullanıcısı barındırılan sunucularda çalışır.
martinstoeckli

2
@martinstoeckli Burada ircmaxwell'e katılıyorum, şifrelemenin parola api'ye ait olduğunu düşünmüyorum. Bununla birlikte, maksimum güvenlik için karmalarınızı şifrelemenin kullanılabilecek ek bir hüküm olduğu not edilebilir.
foochow

2
Ben işaret edildi OWASP Uygulama Güvenliği Doğrulama Standardı 4.0 “bir anahtar türetme işlevi ek bir yineleme yapılır emin olun, gizli ve sadece bildiği bir tuz değeri kullanarak: (biber aka) gizli tuz kullanımı önerir bölüm 2.4.5 doğrulayıcı. "
Michael Freidgeim

27

Yumruk , bir biberin tam avantajı hakkında konuşmalıyız :

  • Biber, saldırganın veritabanına okuma erişimine sahip olduğu (karmaları içeren) ancak biberle kaynak koduna erişemediği özel durumda, zayıf parolaları bir sözlük saldırısından koruyabilir.

Tipik bir senaryo, SQL enjeksiyonu, atılmış yedeklemeler, atılmış sunucular olabilir ... Bu durumlar göründüğü kadar nadir değildir ve genellikle kontrolünüz altında değildir (sunucu barındırma). Eğer kullanırsan...

  • Şifre başına benzersiz bir tuz
  • BCrypt gibi yavaş bir hash algoritması

... güçlü parolalar iyi korunur. Bu koşullar altında, tuz bilindiğinde bile güçlü bir parolayı zorlamak neredeyse imkansızdır. Sorun, kaba kuvvet sözlüğünün bir parçası olan veya bunların türevleri olan zayıf parolalardır. Bir sözlük saldırısı bunları çok hızlı bir şekilde ortaya çıkaracaktır çünkü sadece en yaygın şifreleri test edersiniz.

İkinci soru, biberin nasıl uygulanacağıdır ?

Biber uygulamanın sıklıkla önerilen bir yolu, karma işlevine geçmeden önce şifre ile biberi birleştirmektir:

$pepperedPassword = hash_hmac('sha512', $password, $pepper);
$passwordHash = bcrypt($pepperedPassword);

Yine de daha iyi bir yol var:

$passwordHash = bcrypt($password);
$encryptedHash = encrypt($passwordHash, $serverSideKey);

Bu sadece bir sunucu tarafı gizli bilgisi eklemeye izin vermekle kalmaz, aynı zamanda gerekli olması durumunda $ serverSideKey'i değiştirmeye de izin verir. Bu yöntem biraz daha fazla çalışma gerektirir, ancak kod bir kez varsa (kitaplık), onu kullanmamak için bir neden yoktur.


Yani kısaca bir biberin bir tuza karşı güvenlik kattığını söylersiniz? Nasıl uygulanacağına dair yardım için teşekkürler.
Glitch Desire

1
@ LightningDust - Biber gizli kaldığı sürece zayıf şifreler için evet. Bazı iyi tanımlanmış tehdit türlerini azaltır.
martinstoeckli

@martinstoeckli kesinlikle bunu uygulamanın iyi bir yolu. Biraz güvenlik deneyimi olan birinin bu yöntemi desteklediğini görmek güzel. Bir MySQL AES_ENCRYPT($passwordHash, $serverSideKey)çağrısı da bunu uygulamanın uygun bir yolu olur mu?
foochow

1
@Foo_Chow - MySQL işlevinin uygulamasını bilmiyorum, ancak IV-vektöründen kaçınmak için EBC modunu kullandıkları görülüyor. Bilinen düz metinle birlikte (karma değerler her zaman aynı karakterlerle başlar), bu bir sorun olabilir. Ana sayfamda bu şifrelemeyi işleyen örnek bir uygulama yayınladım.
martinstoeckli

@martinstoeckli ilginç, kavramlara çok aşina değil; ancak en sağlam sonuçlar için bir IV arzu edilir gibi görünüyor. Ek fayda için fazla ek yük getirmiyor gibi görünüyor.
foochow

3

Tuz ve biberin amacı, gökkuşağı tablosu adı verilen önceden hesaplanmış bir parola aramasının maliyetini artırmaktır.

Genel olarak, tek bir hash için bir çarpışma bulmaya çalışmak zordur (hash'in güvenli olduğunu varsayarsak). Bununla birlikte, kısa karmalarla, bir sabit diske bir aramaya tüm olası karmaları oluşturmak için bilgisayarı kullanmak mümkündür. Buna Gökkuşağı Masası denir. Bir gökkuşağı tablosu oluşturursanız, daha sonra dünyaya gidebilir ve herhangi bir (tuzsuz bibersiz) karma için hızlıca makul şifreler bulabilirsiniz.

Bir biberin amacı, şifre listenizi kırmak için gereken gökkuşağı tablosunu benzersiz kılmaktır. Böylece saldırgana gökkuşağı masasını inşa etmek için daha fazla zaman harcar.

Ancak tuzun amacı, her kullanıcı için gökkuşağı tablosunun kullanıcıya özgü olmasını sağlamak ve saldırının karmaşıklığını daha da artırmaktır.

Gerçekte, bilgisayar güvenliğinin amacı, onu neredeyse hiçbir zaman (matematiksel olarak) imkansız, sadece matematiksel ve fiziksel olarak pratik yapmamaktır (örneğin, güvenli sistemlerde, tek bir kullanıcının parolasını hesaplamak için evrendeki tüm entropiyi (ve daha fazlasını) gerekir).


Öyleyse tuz + biber, tuzdan daha fazla güvenlik sağlar mı? Yoksa biberi atıp daha fazla scrypt yinelemesini çalıştırsam daha mı iyi olur?
Glitch Desire

2
Gökkuşağı tablosu ile ilgili en önemli şey, belirli bir saldırı için bir tane oluşturmamanız, önceden var olan bir tanesini indirmenizdir. Popüler karma algoritmalar için yalnızca bir google uzaklıkta uzun gökkuşağı tabloları var!
Richard

1
@LightningDust Kendim için herhangi bir sebep düşünemiyorum. Ancak diğer başlıktaki Richard bir tane buldu. Biberleri kaynak kodunuzda gizleyebilirsiniz, bu da saldırganınızın bir gökkuşağı masasını bir araya getirmek için erişmesi gereken başka bir yer anlamına gelir.
Aron

@Aron - Ben de öyle düşünmüştüm, çünkü veritabanı sunucularından ayrı uygulama sunucularımız var (yani, rootdb sunucumuza girerseniz, uygulama sunucumuza hala erişiminiz yok), kaynak kodunda biber gizleyen yapılandırma dosyamız) ek güvenlik sağlayacaktır.
Glitch Desire

2

Bunun belirli algoritmalar değil, tuz ve biber tartışması olmasını istiyorum, ancak güvenli bir tane kullanıyorum

Bildiğim her güvenli parola karma işlevi, parolayı ve tuzu (ve destekleniyorsa sırrı / biberi) ayrı bağımsız değişkenler olarak alır ve tüm işi kendisi yapar.

Sırf dizeleri bir araya getirdiğiniz ve hash_functionyalnızca bir argüman aldığınız gerçeğiyle, iyi test edilmiş, iyi analiz edilmiş standart algoritmalardan birini kullanmadığınızı, bunun yerine kendinizinkini döndürmeye çalıştığınızı biliyorum. Bunu yapma.

Argon2 , 2015 yılında Password Hashing Yarışması'nı kazandı ve bildiğim kadarıyla yeni tasarımlar için hala en iyi seçim. Biberi K parametresi ("gizli değer" veya "anahtar" olarak adlandırılır) aracılığıyla destekler. Biber kullanmamak için hiçbir sebep bilmiyorum. En kötüsü, veri tabanıyla birlikte biber de tehlikeye atılacak ve kullanmadığınızdan daha kötü durumda değilsiniz.

Yerleşik biber desteğini kullanamıyorsanız, bu tartışmada önerilen iki formülden birini kullanabilirsiniz :

Argon2(salt, HMAC(pepper, password))   or   HMAC(pepper, Argon2(salt, password))

Önemli not: HMAC (veya başka bir karma işlevi) çıktısını Argon2'ye (veya başka bir şifre karma işlevine) iletirseniz, şifre karma işlevinin gömülü sıfır baytları desteklediğinden emin olun veya karma değerini kodlayın (ör. Base64'te ) sıfır bayt olmadığından emin olmak için. Dizeleri gömülü sıfır baytları destekleyen bir dil kullanıyorsanız, muhtemelen güvendesiniz, bu dil PHP değilse , ama yine de kontrol ederim.


1

Kaynak kodunuzda sabit kodlanmış bir değer depolamanın herhangi bir güvenlikle ilgili olduğunu göremezsiniz. Belirsizlik yoluyla güvenliktir.

Bir bilgisayar korsanı veritabanınızı ele geçirirse, kullanıcı parolalarınızı kaba bir şekilde zorlamaya başlayabilir. Birkaç şifreyi kırmayı başarırsa, o bilgisayar korsanının biberinizi tanımlaması uzun sürmez.


1
Tuzsuz bir şifre tablosu için önceden hesaplanmış bir gökkuşağı tablosunu işe yaramaz hale getirir. Kısacası, saldırgan biberinizi bilse bile yeni bir gökkuşağı masası oluşturması gerekir.
Aron

3
Veritabanında bulunmayan verilere dayanarak hash'i güçlendirir, bu iyi bir şeydir. Veritabanındaki şeyler güvenlik açıklarında potansiyel olarak ortaya çıkabilir - koddaki bir değere aynı şekilde erişilmesi daha az olasıdır.
Richard

Tuzlar tek yönlü işlevlerdir, bir parolayı kaba bir şekilde zorlamak bile size yalnızca bu parolayı verir ve biber değerini elde etmenize yardımcı olmaz.
Glitch Desire

1
@LightningDust Sanırım "Hash'lar tuzak kapısı işlevleridir". Evet, güvenli bir haşhaştan tuzunuzu ve / veya biberinizi bulmak imkansızdır (aslında bu, güvenli bir esrarın tanımıdır).
Aron

6
@Aron Security Through Obscurity, bir savunma katmanı olarak kullanılan geçerli bir teknik olabilir. Mesele şu ki, ona asla bir savunma olarak güvenilmemeli, bunun yerine "bir saldırganı yavaşlatmak" için kullanılmalıdır. Durum böyle olmasaydı, bal kabı gibi bir şey kullanılmazdı. Bunun yerine, uygulamamızın güvenliği için ona güvenmediğimiz sürece, saldırganların yavaşlamasına yardımcı olmak için belirsizlik yoluyla güvenliği etkili bir şekilde kullanabiliriz.
ircmaxell
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.