Soru:
Şifreleme ve kriptoloji ile ilgili alınan dersler ve yanlış anlamalar
goodguys_activate
2011-02-20 01:25:34 UTC
view on stackexchange narkive permalink

Kriptoloji o kadar geniş bir konudur ki, deneyimli kodlayıcılar bile neredeyse her zaman ilk birkaç kez hata yapar. Ancak şifreleme o kadar önemli bir konu ki, çoğu zaman bu hataları göze alamayız.

Bu sorunun amacı, belirli bir algoritma veya API ile yapılmayacağını belirlemek ve listelemektir. Bu şekilde başkalarının deneyimlerinden ders çıkarabilir ve kötü uygulamaların yayılmasını önleyebiliriz.

Bu soruyu yapıcı tutmak için lütfen

  1. "yanlış" bir örnek ekleyin
  2. Bu örnekte neyin yanlış olduğunu açıklayın
  3. Doğru bir uygulama sağlayın (varsa).
  4. Elinizden gelen en iyi şekilde, yukarıdaki 2 ve 3 numaralı referanslar sağlayın.
En yaygın hatalar koddaki hatalar değil, kriptografinin nasıl kullanılacağına dair yanlış anlamalardır. Başka bir deyişle, geliştirici muhtemelen herhangi bir dilde aynı hatayı yapacaktır. Bu nedenle, koda odaklanmaması için soruyu genişletmenizi öneririm; çoğu hata kodlama hataları değil kavramsal hatalardır.
Bir cevap kabul edilse bile, öğrenilen dersleri eklemeye devam edin. En azından eğitici olacak.
Ayrıca Colin Percival'den (tarsnap) kısa ve kolay sunum: http://www.bsdcan.org/2010/schedule/attachments/135_crypto1hr.pdf
"Yapma" listelerini okumanız gerekiyorsa kriptografi yapmayın. Kriptografide uzmanlaşmış bir güvenlik mühendisinden size yardım etmesini isteyin. :)
İlgili meta tartışma: ["Kendi şifrelemenizi yuvarlamak" ile "bir standart uygulamak" arasındaki açıklama] (http://meta.security.stackexchange.com/q/1119/396)
"Yapma" listesine hazır olmanız gerekmediğini düşünüyorsanız çoğu durumda kriptografi yapmayın (https://en.wikipedia.org/wiki/Dunning%E2%80%93 Kruger Effect) - Dave uygulamasının güvenli olduğundan emindi.
Bu soru bazı çok önemli konuları kapsasa da, formatı SE siteleri için pek uygun değildir, çünkü temelde iyi çalışmayan bir "X listesi" için sorgulama yapıyor.
21 yanıtlar:
D.W.
2011-02-20 09:52:34 UTC
view on stackexchange narkive permalink

Kendi şifrenizi yuvarlamayın.

Kendi şifreleme algoritmanızı veya protokolünüzü icat etmeyin; bu son derece hataya açıktır. Bruce Schneier'in dediği gibi,

"Herkes kendi başına kıramayacağı bir şifreleme algoritması icat edebilir; kimsenin kıramayacağı bir algoritma icat etmek çok daha zordur".

Kripto algoritmaları çok karmaşıktır ve güvenli olduklarından emin olmak için yoğun bir inceleme gerektirir; Kendinizinkini icat ederseniz, bunu elde edemezsiniz ve farkına varmadan güvensiz bir şeyle karşılaşmanız çok kolaydır.

Bunun yerine, standart bir şifreleme algoritması ve protokolü kullanın. Muhtemelen bir başkası sorununuzla daha önce karşılaştı ve bu amaç için uygun bir algoritma tasarladı.

En iyi durumunuz, yüksek düzeyde iyi incelenmiş bir şema kullanmaktır: iletişim güvenliği için TLS (veya SSL ); hareketsiz veriler için GPG (veya PGP) kullanın. Bunu yapamazsanız, cryptlib, GPGME, Keyczar veya NaCL gibi üst düzey bir kripto kitaplığı kullanın. OpenSSL, CryptoAPI, JCE vb. gibi düşük seviyeli biri. Bu öneri için Nate Lawson'a teşekkürler.

Aslında bu, diğer tüm kurallarımızı geçersiz kılacak olan 1 numaralı kural olmalıdır. Dünyada muhtemelen kripto tasarlaması veya uygulaması gereken birkaç yüz kişi var. Geri kalanımız kendi (aklı başında) API'lerini kullanmalıyız.
Bir .NET geliştiricisi için en iyi seçenek nedir? Herhangi bir eğitim veya örnek var mı? Kripto uzmanı olmayan birinin yanlış bilgileri geçerli olandan tespit etmesi zordur.
Geçmişte zor sorunları çözen yaratıcı mühendis için kriptoyu başka birine bırakmak özellikle cazip geliyor. Hala kripto dışında çözülmesi gereken çok sayıda zor ve etkili sorun var. Kriptoda kritik hatalar yapan ve başka bir şeyi çözen kişilerin örneklerine bakın.
+1 Crypto API, meslekten olmayan geliştiricinin başını belaya sokabilecek çok fazla esneklik sunuyor. İnternette (ve MSFT'nin destek sitesinde) bu sayfada öğrenilen derslerden en az birini ihlal eden birçok örnek var. Bazı geliştiriciler, anahtarların nasıl değiş tokuş edildiği, onaylandığı ve iptal edildiği gibi şeyleri düşünmeyi unutur. İşler burada dikenli hale geliyor. Anahtarlar nerede tutuluyor? Anahtarlar nasıl yayınlanır? Anahtarlar nasıl doğrulanır? Anahtar rotasyonu nasıl yapılır? Geliştirici matematiği doğru veya özelliklerin kombinasyonunu (CBC, Blok, akış vb.) Elde edecek kadar şanslı olsa bile, protokol bozulmuş olabilir.
.Net için yüksek seviyeli bir seçenek için [keyczar'ı C #'ye] taşıdım (http://jbtule.github.com/keyczar-dotnet/).
[Bunu] (http://www.isg.rhul.ac.uk/tls/) gördüğümüzde, ince baskılar olmadan "TLS kullanmak" o kadar da iyi bir fikir değildir
Kriptoyu icat etmemek bir kriptoloji kuralı olamaz ve mevcut bazı API veya algoritmaların kötüye kullanımı değildir.
D.W.
2011-02-20 09:36:29 UTC
view on stackexchange narkive permalink

İleti kimlik doğrulaması olmadan şifreleme kullanmayın

Verilerin kimliğini doğrulamadan şifrelemek çok yaygın bir hatadır.

Örnek: Geliştirici bir mesajı gizli tutmak istiyor, bu nedenle mesajı AES-CBC modu ile şifreler. Hata: Bu, etkin saldırılar, yeniden oynatma saldırıları, tepki saldırıları vb. Durumlarda güvenlik için yeterli değildir. İleti kimlik doğrulaması olmadan şifrelemeye yönelik bilinen saldırılar vardır ve saldırılar oldukça ciddi olabilir. Düzeltme, mesaj kimlik doğrulaması eklemektir.

Bu hata, ASP.NET, XML a dahil olmak üzere kimlik doğrulama olmadan şifreleme kullanan konuşlandırılmış sistemlerde ciddi güvenlik açıklarına yol açtı. > şifreleme, Amazon EC2, JavaServer Faces, Ruby on Rails, OWASP ESAPI, IPSEC, WEP, ASP.NET tekrar ve SSH2. Bu listede bir sonraki olmak istemezsiniz.

Bu sorunları önlemek için, şifrelemeyi her uyguladığınızda mesaj kimlik doğrulamasını kullanmanız gerekir. Bunu nasıl yapacağınıza dair iki seçeneğiniz vardır:

  • Muhtemelen en basit çözüm, kimliği doğrulanmış şifreleme sağlayan bir şifreleme şeması kullanmaktır, ör. GCM, CWC, EAX, CCM, OCB. (Ayrıca bkz .: 1.) Kimliği doğrulanmış şifreleme şeması bunu sizin yerinize halleder, böylece bunun hakkında düşünmeniz gerekmez.

  • Alternatif olarak, aşağıdaki gibi kendi mesaj kimlik doğrulamanızı uygulayabilirsiniz. İlk olarak, uygun bir simetrik anahtar şifreleme şeması (örneğin, AES-CBC) kullanarak mesajı şifreleyin. Ardından, tüm şifreli metni alın (tüm IV'ler, şifreler veya şifre çözme için gerekli diğer değerler dahil), bir mesaj kimlik doğrulama kodu (örn., AES-CMAC, SHA1-HMAC, SHA256-HMAC) uygulayın ve elde edilen MAC özetini iletimden önce şifreli metin. Alıcı tarafta, şifre çözmeden önce MAC özetinin geçerli olup olmadığını kontrol edin. Bu, şifreli ve sonra kimlik doğrulama yapısı olarak bilinir. (Ayrıca bkz .: 1, 2.) Bu da iyi çalışıyor, ancak sizden biraz daha fazla özen göstermenizi gerektiriyor.

C # ve Java kullanıcıları [BouncyCastle] (http://www.bouncycastle.org/csharp/) sayfasına bakmalıdır.
@makerofthings7: GCM şifrelemesi, Java 7 içindeki Oracle sağlayıcısına dahildir. Ayrıca TLS (bir RFC içinde) ve XML şifreleme v1.1 için de önerilir. Bouncy uygulaması, Sun sağlayıcısındaki ile uyumludur (kimliği doğrulanmış verilerle ilgili farklılıklar ve atılan tam istisna hariç).
Kriptografide yeni olanlar için (dolayısıyla bu yazıyı okuyan) "Kimlik Doğrulamasının" "Oturum açmak" veya kimlik bilgilerinizi kullanmakla ilgisi yoktur. Sağlama toplamı gibi bir şey. Gerçekte, matematik ve süreçlerin birleşimi, sonuçta verileri basitçe sağlama toplamından çok daha fazlasını yapar. (@D.W. Bu meslekten olmayan kişi açıklaması hakkında ne düşünüyorsunuz?)
@makerofthings7, harika bir açıklama! Belki de makalenin genel kimlik doğrulamasından ziyade "ileti kimlik doğrulamasına" atıfta bulunması daha net olacaktır. Şimdi bu değişikliği yapacağım.
D.W.
2011-02-20 11:29:57 UTC
view on stackexchange narkive permalink

Birden çok dizeyi birleştirirken dikkatli olun, karma oluşturmadan önce.

Bazen gördüğüm bir hata: İnsanlar S ve T dizelerinin bir karmasını istiyorlar. tek dizge S || T, sonra hash ile H (S || T) elde edin. Bu hatalı.

Sorun: Birleştirme, iki dizi arasındaki sınırı belirsiz bırakıyor. Örnek: yerleşik || güvenli = oluşturulmuş || güvensiz . Başka bir deyişle, hash H (S || T), S ve T dizisini benzersiz bir şekilde tanımlamaz. Bu nedenle, saldırgan, hash'i değiştirmeden iki dizge arasındaki sınırı değiştirebilir. Örneğin, Alice yerleşik ve güvenli dizelerini göndermek isterse, saldırgan bunları oluşturulmuş ve karmaşayı geçersiz kılmadan güvenli değildir.

Bir dizi diziye dijital imza veya mesaj kimlik doğrulama kodu uygulanırken benzer sorunlar söz konusudur.

Düzeltme: düz birleştirme yerine, açık bir şekilde çözülebilen bazı kodlamalar kullanın. Örneğin, H (S || T) hesaplamak yerine, H (uzunluk (S) || S || T) hesaplayabilirsiniz; burada uzunluk (S), S'nin uzunluğunu bayt cinsinden ifade eden 32 bitlik bir değerdir. Veya başka bir olasılık, H (H (S) || H (T)) veya hatta H (H (S) || T) kullanmaktır.

Bu kusurun gerçek hayattan bir örneği için , Amazon Web Hizmetleri'ndeki bu kusur veya Flickr'daki bu kusur [pdf] bölümüne bakın.

Genelde ona HMAC atıyorum. Biraz daha pahalı, ama en azından kendim uygulamaya ihtiyacım yok.
@CodeInChaos, bu sorunlar HMAC için de aynı şekilde geçerlidir. Birkaç dizeyi HMAC'a beslemeden önce birleştirirseniz HMAC hiçbir şey yapmaz.
Demek istediğim, birini anahtar, diğerini mesaj olarak kullanıyorum.
@CodeInChaos,, eğer kriptografik becerilerinizden kusurları önlemek için yeterince eminseniz, sizin için uygun olanı kullanın. Şahsen, bu yaklaşımı başkalarına tavsiye etmem. (1) HMAC bunun için tasarlanmadı, bu yüzden güvenli olursa, "şanslısınız". (2) Bu, iki alan durumuyla sınırlıdır. Üç alanınız varsa, daha karmaşık bir şey yapmanız gerekir. Bu nedenle, açık bir şekilde çözülebilir bir kodlama kullanmak gibi (örneğin, birleştirilecek her alandan önce önceden eklenmiş uzunluk), başlangıçtan itibaren uygun bir savunma kullanabilir.
H (H (S) || H (T)) nasıl olur? H () 'nin çıktısı sabit bir uzunluk olduğundan, sınırı hareket ettiremezsiniz. Ayrıca, birleştirme için girdi olarak hash kullanmak, girdilerden birinin bir tarafındaki bir dizeyi istenen bir değere dönüştürmeyi gerçekten zorlaştırır. Gördüğüm tek dezavantaj, şimdi bir yerine 3 karma yapıyor olmanız. Ama yine de, hash'lerin yavaş olması gerekiyordu, bu yüzden belki de kötü bir şey değil;)
@Marcin, evet, bunu yapmanın başka bir makul yolu. Önerinizi cevabıma ekledim. Önerin için teşekkürler! (Bunun iyi bir çözüm olmadığı bazı çok belirsiz durumlar olabilir - örneğin, S'nin bir sır olduğu, H (S) 'nin kamuya açık bir bilgi olduğu, T'nin bir meydan okuma olduğu ve amaç, gönderenin S bilgisini kanıtlamasını sağlamaktı. S ve T'nin bir karmasını geri göndererek - ancak bu çok nadir görülen özel durumlar için endişelenmeyeceğim.)
@Marcin "_ kısaltmaların yavaş olması gerekiyor" hayır, yavaş olmaları ** ** değil ** ve yavaş da ** değiller **
Buradaki gereklilik, sınırı açık bir şekilde bilmektir: hash-concatenate-hash yaklaşımı, bir öğe dışında en azından hepsine hash uygulamanızı gerektirir - bilinen bir konumdaki bir öğe, hashing uygulanmadan bırakılabilir. Böylece, kimlik doğrulama için kullanılan bilinen bir miktar ise H (S) kullanmaktan kaçınabilirsiniz - bunun yerine S kullanmak ancak diğer tüm bileşenlere hashing uygulamak. Yine de dikkatli olun, altta yatan matematik sizi birleştirme ve yeniden hashing varyantları altında ısırabilir.
Ben bir kripto-n00b'im, bu nedenle bu aptalca bir soru olabilir, ancak "yerleşik" ve "güvenli" iki dizenin karmasını almaya çalışıyorsanız, neden karma H ("yerleşik" || [somedelimiter " ] || `güvenli bir şekilde`)?
@Matt, evet, işe yarayabilir! Bununla birlikte, bu dizelerde herhangi bir sınırlayıcı örneğinden kaçınmanız gerekir (aksi takdirde, kaçınılmaz olarak, birisi sınırlayıcıyı içeren bir dize yazacak ve sonra bu yaklaşım başarısız olacaktır). Bu, alternatiflerde bulunmayan karmaşıklığı ekler. Ve bunu başkalarına tavsiye ederseniz, kaçınılmaz olarak izleyicilerinizden biri sınırlayıcılardan kaçmayı unutacaktır. Sınırlayıcıdan kaçmayı unuturlarsa, bu şema sessizce başarısız olur: güvensizdir, ancak muhtemelen normal çalışmada bunu fark etmeyeceklerdir. Yani, evet işe yarıyor - ama bu benim ilk tercihim olmayabilir.
`H (json_encode (array (" yerleşik "," güvenli bir şekilde ")))` bunu yapabilir. Ve @penguat. Realex Payments, kredi kartlarının işlenmesinde bu formun bir karmasını kullanır: `H (H (çeşitli) | gizli)`.
Ne ??? Bu cevap mantıklı değil. Veriler belirsiz ise, bir saldırgan olması gerekmez. Alice, Bob bir boşluk koymadığı için "yerleşik güvenli olmayan" yorumlamayı bilmiyor. Bu belirsizlik, saldırgan tarafından ortaya konan bir sorun değildir, daha ziyade seçilen veri sunumunda içseldir. Katenat yapamazsak herhangi bir şeyi nasıl sindirebiliriz? Bir bitten uzun her mesaj bir mesajdır.
@Kaz,, şifrelemeye girişin biçimlendirilmesinden bahsediyor olsaydık (alıcının şifresini çözeceği ve sonra düz metni anlamaya çalışacağı), kafanız karışan karışıklık tamamen geçerli olacaktır. Ama buradaki durum bu değil. Burada girdiyi bir hash işlevine biçimlendirmekten bahsediyoruz. Burada şifre çözmenin bir analoğu yoktur; alıcı hiçbir zaman düz metni almaz ve sonra onu ayrıştırmaya çalışır. Bunun yerine, alıcı aynı düz metni yeniden oluşturur, ona hash uygular ve gönderenin gönderdiği hash ile eşleşip eşleşmediğini görür. Bu nedenle, bir saldırganın yokluğunda protokol iyi çalışıyor gibi görünecektir.
@D.W. Şifrele mi dedim? "Özet" yazmak istedim. İşte, düzeltti. İyi bir şey s.e. yorumları yazıldıktan saatler sonra düzenlememize izin verir.
Tamam, yani "yerleşik" ve "güvenli" olmak üzere iki dizimiz var. "Yapısal olarak güvenli olmayan" bir sınır olmaması için onları bir araya getiriyoruz. Bölünmenin nerede olduğu mesajda hiçbir şekilde temsil edilmez. Çerçeve biti veya baytı yok, uzunluk alanı yok, hiçbir şey yok. Ve sonra hash ediyoruz. Ve şimdi saldırgan "sınırı değiştiriyor". Saldırgan, orada olmayanı * nasıl * değiştirir *?
Ve eğer iki biti bir araya getirip onları karıştırırsam, dizeleri beslemem değil mi? Bu nedenle, tanımlanması için her biti ayrı ayrı hash etmeliyiz. Saldırganların sınırları bitler arasında hareket ettirmesini istemeyiz, böylece 00 1 aniden 0 11 olur.
@Kaz, işte birkaç kez gördüğüm bir durum: gönderen "yerleşik" ve "güvenli" olmak üzere iki bölümden oluşan bir mesaj gönderir. Mesaj açık metindir ve mesajda bölme açıkça belirtilmiştir. Bütünlüğünü korumak için gönderen, mesaj parçalarının birleştirilmesine bir MAC veya sağlama veya imza ekler. Kusur: ortadaki adam, mesajı yerleşik / güvenli bir şekilde inşa edilmiş / güvensiz olarak değiştirebilir; her ikisi de aynı karma / imzaya / MAC'ye sahiptir, bu nedenle alıcı bunu algılayamaz. Bunun nasıl daha ayrıntılı olabileceğini anlamak için bağlantı verdiğim iki örneği (AWS ve Flickr) okuyun. Evet, bu * gerçek bir kusurdur.
@DW Evet, bölme mesajda açık olduğundan, ancak bu bitler karmaya dahil edilmemiştir !!! Yükü hash etmeyin ve başlık veya meta verileri dışarıda bırakmayın. Tüm mesajı özetleyin. Bu bir katenasyon sorunu değil. Bir hash'den hariç tuttuğunuz her şey, ne olduğuna bakılmaksızın onun tarafından korunmaz. Yükü iki parçaya, zaman damgasına veya başka herhangi bir şeye bölen uzunluk alanı.
Alex Holst
2011-02-20 02:11:32 UTC
view on stackexchange narkive permalink

Nonce'leri veya IV'leri yeniden kullanmayın

Çoğu işlem modu bir IV (Başlatma Vektörü) gerektirir. Bir IV için asla aynı değeri iki kez tekrar kullanmamalısınız; bunu yapmak, tüm güvenlik garantilerini iptal edebilir ve feci bir güvenlik ihlaline neden olabilir.

  • CTR modu veya OFB modu gibi akış şifreleme işlem modları için IV'ü yeniden kullanmak, güvenlik felaketi. Şifrelenmiş mesajların önemsiz bir şekilde kurtarılabilir olmasına neden olabilir.

  • CBC modu gibi diğer çalışma modları için IV'ün yeniden kullanılması, bazı durumlarda düz metin kurtarma saldırılarını da kolaylaştırabilir. .

Hangi çalışma modunu kullanırsanız kullanın, IV'ü tekrar kullanmamalısınız. Nasıl doğru yapılacağını merak ediyorsanız, NIST belirtimi, blok şifreleme işlem modlarının doğru şekilde nasıl kullanılacağına dair ayrıntılı belgeler sağlar.

Tarsnap projesi, bu tuzak. Tarsnap, yedekleme verilerini parçalara bölerek ve ardından her bir parçayı CTR modunda AES ile şifreleyerek şifreler. Tarsnap'ın 1.0.22 ila 1.0.27 sürümlerinde, aynı IV yanlışlıkla yeniden kullanıldı ve düz metin kurtarmayı mümkün kıldı.

Bu nasıl oldu? Colin Percival, Tarsnap kodunu basitleştirmek için - ve hata potansiyelini azaltma umuduyla - AES-CTR kodunu yeni bir dosyada (Tarsnap kaynak kodunda lib / crypto / crypto_aesctr.c) "yeniden düzenleme" fırsatını kullandı. ) ve bu rutinlerden yararlanmak için AES-CTR'nin kullanıldığı mevcut yerleri değiştirdi. Yeni kod şuna benzer:

 / * Verileri şifreleyin. * / - aes_ctr (& encr_aes-> anahtar, encr_aes-> nonce ++, buf, len, - filebuf + CRYPTO_FILE_HLEN); + if ((stream = + crypto_aesctr_init (& encr_aes-> anahtar, encr_aes-> nonce)) == NULL) + goto err0; + crypto_aesctr_stream (akış, buf, filebuf + CRYPTO_FILE_HLEN, len); + crypto_aesctr_free (akış); 

Yeniden düzenleme sırasında, encr_aes->nonce ++ yanlışlıkla encr_aes->nonce 'a dönüştürüldü ve sonuç olarak aynı nonce değeri tekrar tekrar kullanıldı . Özellikle, CTR nonce değeri, her parça şifrelendikten sonra artırılmaz. (CTR sayacı, her 16 baytlık veri işlendikten sonra doğru şekilde artırılır, ancak bu sayaç her yeni yığın için sıfırlanır.) Tüm ayrıntılar Colin Percival tarafından http://www.daemonology.net adresinde açıklanmıştır. /blog/2011-01-18-tarsnap-critical-security-bug.html

Sorun bir nonce etrafında merkezlendiğinden, bu yanıta bu etkiye başlık eklemeyi deneyin (+1); S: Nonce genellikle ++ mı yoksa rastgele mi olmalıdır?
@makerofthings, algoritmasına bağlıdır. Bazı algoritmalar ve işlem modları rastgele olmayanlar gerektirir (örneğin, CBC modu); diğerleri yalnızca nonces'lerin farklı olmasını gerektirir ve bu nedenle bir sayaç yeterlidir (örneğin, CTR modu). Umarım, algoritma / işlem modu için spesifikasyon neyin gerekli olduğunu açıklar.
Cevabın IV'leri de içerecek şekilde düzenlenmesini öneririm. Doğru IV / nonce kullanımı çok benzer fikirlerdir.
Nonce bir kez N'dir. Evet, N değişkenini yalnızca bir kez kullanın. Tekil. Tekrarlama. N tekrarlanarak ilişkili algoritmanın gücü zarar görür.
İşte yanlış bir örnek: WEP, her mesajdan sonra artan 24 bitlik nonce ile RC4'ü uyguladı. Bu, iki sorunu ortaya çıkardı: (1) 2 ^ 24 paket gönderildikten sonra, nonce'ler yeniden kullanıldı. (2) RC4, birbirini izleyen her şifrenin bir öncekinin değeri ++ olduğu bilindiği durumlarda "yakından ilişkili" olmayanlara sahip olacak şekilde tasarlanmamıştır.
İşte doğru bir örnek: Bir kripto tasarımcısının aynı anahtarı birden çok mesaj için yeniden kullanmak istemediğini varsayalım. Çözümlerden biri, bir anahtar oluşturmak ve bunu bir PRG kullanarak genişletmektir. Daha sonra anahtar olarak yalnızca "x" bitlerinin her bir katını kullanın. Burada segment 1 == anahtar 1, segment 2 == anahtar 2.
D.W.
2011-02-20 10:06:23 UTC
view on stackexchange narkive permalink

Yeterli entropi ile rastgele sayı oluşturucuları yerleştirdiğinizden emin olun.

Anahtar oluşturmak, IV'leri / hiçleri seçmek vb. gibi şeyler için kripto gücü sözde rasgele sayı üreteçleri kullandığınızdan emin olun . rand () , random () , drand48 () vb. Kullanmayın.

Emin olun sahte rasgele sayı üretecini yeterli entropi ile tohumlayın. Onu günün saatiyle tohumlamayın; bu tahmin edilebilir.

Örnekler: srand (time (NULL)) çok kötü. PRNG'nizi yerleştirmenin iyi bir yolu, 128 bit veya gerçek rastgele sayılar almaktır, örneğin / dev / urandom , CryptGenRandom veya benzerinden. Java'da, Rasgele değil SecureRandom kullanın. .NET'te System.Random'u değil System.Security.Cryptography.RandomNumberGenerator'ı kullanın. Python'da rastgele değil, random.SystemRandom kullanın. Bazı örnekler için Nate Lawson'a teşekkürler.

Gerçek dünya örneği: Netscape tarayıcısının ilk sürümlerinde bir saldırganın SSL'yi kırmasına izin veren bu kusura bakın.

Apple'ımda Basic'i öğrendiğimi hatırlıyorum] [e. Bir oyun yazıyordum ve rastgele girdiye ihtiyacım vardı, bu yüzden RND (1) kullandım. Oyunumda hata ayıklamak için yeniden başlatmam gerekiyordu ve rastgele öğenin önyüklemeden sonra her zaman aynı sırada gittiğini fark ettim. O zaman sahte rasgele sayı üreteçlerini öğrendim. Bazı rastgele tohumlara ihtiyacınız varsa, Random.org, atmosferik gürültüye dayalı ücretsiz rastgele sayı üretimi sunar.
Random.org, simülasyon ve diğer güvenlik dışı amaçlar için en iyisidir. Random.org, kriptografik bir PRNG tohumu için iyi bir temel değildir, çünkü başkalarının bilmediğine güvenemezsiniz.
goodguys_activate
2011-02-20 01:34:06 UTC
view on stackexchange narkive permalink

Simetrik şifreleme için ECB ile blok şifreleme kullanmayın

(AES, 3DES, ... için geçerlidir)

İşte bir gönderi ve ECB modunun nasıl şifrelenmemiş bir kodla sonuçlandığına dair çok benzer bir Microsoft KB makalesi.

Ayrıca Rook 'dan bu benzer gönderiye bakın

Düz metin mesajı:

alt text

ECB modu ile şifrelenen mesajın aynısı (hangi şifreyi kullandığınız önemli değil): alt text

CBC modunu kullanan TAM aynı mesaj (yine, ne olduğu önemli değil kullandığınız şifre): alt text

Yanlış yol

  public static string Encrypt (string toEncrypt, string key, bool useHashing) { bayt [] keyArray = UTF8Encoding.UTF8.GetBytes (anahtar); bayt [] toEncryptArray = UTF8Encoding.UTF8.GetBytes (toEncrypt); if (useHashing) keyArray = new MD5CryptoServiceProvider (). ComputeHash (anahtar); ComputeHash (anahtar) ) {Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7}; ICryptoTransform cTransform = tdes.CreateEncryptor (); bayt [] resultArray = cTransform.TransformFinalBlock (toEncryptArray, 0, toEncryptArray; (resultArray, 0, resultArray.Length);}  

Hata aşağıdaki satırdadır

{Key = keyArray, Mode = CipherMode.ECB , Padding = PaddingMode.PKCS7};


Doğru yol

Microsoft'taki iyi arkadaşlar, yukarıda bağlantısı verilen KB makalesini düzeltmem için bana aşağıdaki kodu gönderdiler. Buna 111021973179005 numaralı durumda başvurulur

Bu örnek kod, verileri şifrelemek için AES kullanıyor ve AES şifrelemesinin anahtarı, SHA256 tarafından oluşturulan karma koddur. AES, Gelişmiş Şifreleme Standardı (AES) algoritmasıdır. AES algoritması permütasyonlara ve ikamelere dayanmaktadır. Permütasyonlar verilerin yeniden düzenlenmesidir ve ikameler bir veri birimini diğeriyle değiştirir. AES, birkaç farklı teknik kullanarak permütasyonlar ve ikameler gerçekleştirir. AES hakkında daha fazla ayrıntı için lütfen http://msdn.microsoft.com/en-us/magazine/cc164055.aspx .

SHA, Güvenli Karma Algoritmadır. SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512) artık önerilmektedir. .NET Framework'te Hash Değerleri hakkında daha ayrıntılı bilgi için lütfen http://msdn.microsoft.com/en-us/library/92f9ye3s.aspx#hash_values ​​ adresine bakın.

AesCryptoServiceProvider için simetrik algoritmanın çalıştırılmasına yönelik modun varsayılan değeri CBC'dir. CBC, Şifreleme Bloğu Zincirleme modudur. Geri bildirimi tanıtır. Her düz metin bloğu şifrelenmeden önce, bit düzeyinde özel OR işlemiyle önceki bloğun şifreleme metni ile birleştirilir. Bu, düz metin birçok özdeş blok içerse bile, her birinin farklı bir şifreleme metin bloğuna şifrelenmesini sağlar. Başlatma vektörü, blok şifrelenmeden önce bit düzeyinde özel VEYA işlemiyle ilk düz metin bloğu ile birleştirilir. Şifreleme metin bloğunun tek bir biti karıştırılırsa, karşılık gelen düz metin bloğu da karıştırılır. Ek olarak, sonraki blokta orijinal karıştırılmış bit ile aynı konumda bulunan bir bit karıştırılacaktır. CipherMode hakkında daha ayrıntılı bilgi için lütfen http://msdn.microsoft.com/en-us/library/system.security.cryptography.ciphermode.aspx adresine bakın.

İşte örnek kod.

  // Bu işlev, verileri anahtar ve iv ile şifrelemek için kullanılır.
bayt [] Şifrele (bayt [] veri, bayt [] anahtar, bayt [] iv) {// Bir AESCryptoProvider oluşturun. using (var aesCryptoProvider = new AesCryptoServiceProvider ()) {// AESCryptoProvider'ı anahtar ve iv ile başlatın. aesCryptoProvider.KeySize = key.Length * 8; aesCryptoProvider.IV = iv; aesCryptoProvider.Key = anahtar; // AESCryptoProvider'dan şifreleyici oluşturun. kullanarak (ICryptoTransform encryptor = aesCryptoProvider.CreateEncryptor ()) {// Şifrelenmiş verileri depolamak için bellek akışı oluşturun. kullanarak (MemoryStream stream = new MemoryStream ()) {// Verileri şifrelemek için bir CryptoStream oluşturun. using (CryptoStream cryptoStream = new CryptoStream (stream, encryptor, CryptoStreamMode.Write)) // Verileri şifreleyin. cryptoStream.Write (veri, 0, veri.Uzunluğu); // şifrelenmiş verileri döndür. return stream.ToArray (); }}}} // Bu işlev, anahtar ve iv.byte [] Şifre çözme (bayt [] veri, bayt [] anahtar, bayt [] iv) {// Bir AESCryptoServiceProvider oluşturarak verilerin şifresini çözmek için kullanılır. using (var aesCryptoProvider = new AesCryptoServiceProvider ()) {// AESCryptoServiceProvier'i anahtar ve iv ile başlatın. aesCryptoProvider.KeySize = key.Length * 8; aesCryptoProvider.IV = iv; aesCryptoProvider.Key = anahtar; // AESCryptoServiceProvider'dan şifre çözücü oluşturun. kullanarak (ICryptoTransform decryptor = aesCryptoProvider.CreateDecryptor ()) {// Şifrelenmiş verileri içeren bir bellek akışı oluşturun. kullanarak (MemoryStream stream = new MemoryStream (data)) {// Şifrelenmiş verilerin şifresini çözmek için bir CryptoStream oluşturun. using (CryptoStream cryptoStream = new CryptoStream (stream, decryptor, CryptoStreamMode.Read)) {// Bir bayt arabellek dizisi oluşturun.
bayt [] readData = yeni bayt [1024]; int readDataCount = 0; // Şifresi çözülmüş verileri depolamak için bir bellek akışı oluşturun. kullanarak (MemoryStream resultStream = new MemoryStream ()) {do {// Verilerin şifresini çözün ve verileri readData arabellek dizisine yazın. readDataCount = cryptoStream.Read (readData, 0, readData.Length); // Şifresi çözülmüş verileri resultStream'e yazın. resultStream.Write (readData, 0, readDataCount); } // Akışta daha fazla şifrelenmiş veri olup olmadığını kontrol edin. while (readDataCount > 0); // Şifresi çözülmüş verileri döndür. sonuçStream.ToArray (); }}}}}} // Bu işlev, UTF8 kodlaması ve SHA256 karma algoritması ile geçerli bir anahtar ikili oluşturmak için kullanılır. Bayt [] GetKey (dize anahtarı) {// SHA256 karma algoritma sınıfı oluşturun. using (SHA256Managed sha256 = new SHA256Managed ()) // Dize anahtarının kodunu ikili olarak çöz ve anahtarın karma ikili değerini hesapla. return sha256.ComputeHash (Encoding.UTF8.GetBytes (key));}  

Örnek koddaki sınıflarla ilgili daha fazla ayrıntı için lütfen aşağıdaki bağlantılara bakın:

· AesCryptoServiceProvider Sınıfı

· SHA256Yönetilen Sınıf

· CryptoStream Sınıfı

Ayrıca, .NET Framework'te şifrelemenin daha iyi anlaşılmasına yardımcı olabilecek birkaç makale vardır, lütfen aşağıdaki bağlantılara bakın:

· Şifreleme Hizmetleri

· .NET Framework Şifreleme Modeli

· Basit Bir Kriptografi Rehberi

· Olmadan Şifreleme Sırlar

"Doğru yol" dan sonra her şeyi silmenizi öneririm. Coda Hale'in önerisinin bir takım zayıf yönleri vardır. Buradaki diğer yanıtlarda belgelediğim birkaç hata yapıyor: mesaj kimlik doğrulaması olmadan şifreleme kullanıyor (ciddi bir kusur), anahtarı bir parolanın karması olarak yaratıyor (ciddi bir kusur), kapsamlı anahtar aramayı yavaşlatma girişiminde bulunmaz (başka bir ciddi kusur). Bunu doğru bir şekilde halletmek için tavsiyem, cevabımın son paragrafında "Kendi kriptoyu döndürmeyin" başlığıyla anlatılıyor.
"Sorumluluk Reddi" ve "bazı önemli noktalar" dan sonraki tüm şeyleri silmenizi öneririm. Bence bunların çoğu, ECB'den kaçınma konusundaki üst düzey noktanızla alakalı değil ve dikkat dağıtıcı. Kısa ve öz olun. Bunun yerine, doğru yol için tavsiyenizin şöyle olması gerektiğini öneririm: CBC modu veya CTR modu gibi güvenli bir çalışma modu kullanın. Mesaj kimlik doğrulamasını kullanmak, uygun şekilde anahtarlar oluşturmak vb. Dahil olmak üzere bu sayfadaki diğer tavsiyelere uymayı unutmayın. Bunu bir topluluk wiki'si yapmak isterseniz, bu yanıtı uygun şekilde düzenlemekten memnuniyet duyarım.
@D.W. Evet, cevaplardan herhangi birini veya tümünü CW olarak düzenlemekten çekinmeyin. Tüm soruyu CW yapmaya karşı olan düşüncem posterleri teşvik etmek, ancak bu kararı size bırakacağım millet. Sadece doğru şeyleri öğrenmek ve kötü uygulamaları unutmak istiyorum
Varsayılan olarak / ECB / PKCS5Padding kullanan Java'da bu hatayı yapmak daha da kolaydır (örneğin, `` Cipher.getInstance ("AES") ") ve CBC'ye geçerseniz sıfırlanmış bir IV kullanır. (aşağı yukarı NONCE, bununla ilgili yanıta bakın) varsayılan olarak da.
Resmi nasıl böyle şifreledin ??
@Matt, bu görüntü başarılı bir saldırının sonucudur. TUX.BMP adlı bir dosya verildiğinde, saldırganın ona bakmaya çalışacağını ancak şifreli olduğunu keşfedeceğini varsayın. Daha sonra şifrelenmiş baytları görüntüler ve rastgele olmayan bir model gördükten sonra CBC'den şüphelenir. Daha sonra ilk çift bloğu bilinen iyi bir BMP dosya başlığıyla değiştirir ve satırlar ve sütunlar aynı hizaya gelene kadar ince ayarlar yapar. Birkaç yıl önce Blackhat'te bir araştırmacının bunu yapmak için bir araç kullandığını gördüm, sanırım bu araca rumint deniyordu.
D.W.
2011-02-20 09:50:34 UTC
view on stackexchange narkive permalink

Hem şifreleme hem de kimlik doğrulama için aynı anahtarı kullanmayın. Hem şifreleme hem de imzalama için aynı anahtarı kullanmayın.

Bir anahtar birden çok amaçla yeniden kullanılmamalıdır; Bu, çeşitli gizli saldırılara yol açabilir.

Örneğin, bir RSA özel / genel anahtar çiftiniz varsa, şifreleme için ikisini birden kullanmamalısınız (açık anahtarla şifreleyin, özel anahtarla şifresini çözün) ve imzalamak için (özel anahtarla imzalayın, açık anahtarla doğrulayın): tek bir amaç seçin ve onu yalnızca bu amaç için kullanın. Her iki yeteneğe de ihtiyacınız varsa, biri imzalama ve diğeri şifreleme / şifre çözme için olmak üzere iki anahtar çifti oluşturun.

Benzer şekilde, simetrik kriptografide, şifreleme için bir anahtar ve ileti kimlik doğrulaması için ayrı bir bağımsız anahtar kullanmalısınız. Aynı anahtarı her iki amaç için de tekrar kullanmayın.

S / MIME bu öneriye karşı çalışıyor mu? AFAIK Sadece bir anahtarım var ve imzalama ve şifreleme yeteneğim var.
IMHO, her iki kullanım için de aynı anahtarları kullanmanın en büyük sorunu, yasa uygulama sorunlarından kaynaklanmaktadır. Pek çok yargı alanında artık şifreleme anahtarlarınızı teslim etmeniz istenebilir ve bu pratikte sizin adınızla oturum açabilecekleri anlamına gelir.
Evet, birçok algoritma imzalama ve şifreleme için aynı anahtar çiftini kullanır, PGP ve S / MIME bariz örneklerdir. Mutlaka matematiksel bir problem değildir.
PGP, imzalama ve şifreleme için aynı anahtar çiftini ** kullanmaz **. Bunun yerine, bir PGP özel anahtarı, imzalama için kullanılan bir ana anahtardan ve şifreleme için kullanılan bir veya daha fazla alt anahtardan oluşur. Alt anahtarlar kullanıcıdan gizlidir, bu nedenle kafa karışıklığı vardır, ancak bunları `gpg --list-secret-keys` kullanarak görüntüleyebilirsiniz.
Chris Dale
2012-06-25 16:46:15 UTC
view on stackexchange narkive permalink

Kerckhoffs'un ilkesi: Anahtar dışında sistemle ilgili her şey herkese açık bilgi olsa bile bir şifreleme sistemi güvenli olmalıdır

Yanlış bir örnek: LANMAN karmaları

LANMAN hash'lerini kimse algoritmayı bilmeseydi anlamak zor olurdu, ancak algoritma bilindikten sonra artık kırmak çok önemsiz hale geldi.

Algoritma aşağıdaki gibidir ( Wikipedia'dan):

  1. Kullanıcının ASCII şifresi büyük harfe dönüştürülür.
  2. Bu şifre 14 bayta boş doldurulmuştur
  3. "Sabit uzunlukta" şifre iki yedi baytlık yarıya bölünmüştür.
  4. Bu değerler iki DES anahtarı oluşturmak için kullanılır, biri her bir 7 baytlık yarımdan
  5. İki anahtarın her biri, sabit ASCII dizesi “KGS! @ # $%” DES-şifrelemek için kullanılır, bu da iki 8 baytlık şifreli metin değeriyle sonuçlanır.
  6. Bu iki şifreli metin değeri, LM karması olan 16 baytlık bir değer oluşturmak için birleştirilir

Artık bu gerçeklerin şifreli metnini bildiğiniz için artık çok Şifreli metni, büyük harf olduğunu bildiğiniz iki şifreli metne kolayca ayırın ve şifrenin muhtemelen sınırlı bir karakter kümesine yol açmasını sağlayın.

Doğru bir örnek: AES şifreleme

  • Bilinen algoritma
  • Teknolojiye göre ölçeklenir. Daha fazla kriptografik güce ihtiyaç duyduğunuzda anahtar boyutunu artırın
D.W.
2011-02-20 11:39:43 UTC
view on stackexchange narkive permalink

Şifreleri şifreleme anahtarı olarak kullanmaktan kaçınmaya çalışın.

Çoğu sistemde yaygın bir zayıflık, bir şifre veya parola ya da bir parola veya parola karması kullanmaktır. şifreleme / şifre çözme anahtarı. Sorun, bunun çevrimdışı anahtar arama saldırılarına karşı oldukça hassas olmasıdır. Çoğu kullanıcı, bu tür saldırılara direnmek için yeterli entropiye sahip olmayan parolaları seçer.

En iyi çözüm, bir parola / paroladan belirleyici olarak üretilen bir anahtar değil, gerçekten rastgele bir şifreleme / şifre çözme anahtarı kullanmaktır.

Ancak, bir parola / parola temelli bir parolayı kullanmanız gerekiyorsa, kapsamlı anahtar aramayı yavaşlatmak için uygun bir şema kullanın. Sözlük aramasını yavaşlatmak için yinelemeli karma (H (H (.... H (şifre) ...))) satırları boyunca) kullanan PBKDF2 'yi öneriyorum. Bu işlemin anahtarı oluşturmak için kullanıcının makinesinde 100 ms sürmesine neden olacak kadar yeterince yineleme kullanın.

Yeni başlayan biri olarak bunu yaptığımı kabul ediyorum. Anahtar rastgele ise ve bu nedenle hatırlanması imkansızsa, anahtarların fiziksel bir biçimde bir yerde saklanmasını mı tavsiye ediyorsunuz? Tamamen rastgele anahtarlarla bir sistemi hayata geçirmenin tek yolu bu.
@AdamCross, * "Anahtar rastgele ise ve bu nedenle hatırlanması imkansızsa, anahtarların fiziksel biçimde bir yerde saklanmasını mı öneriyorsunuz?" * - Bir yerde saklanmış, elektronik veya fiziksel biçimde olabilir. Elektronik olmayan formun her durumda elektronik forma göre ayrıcalıklı olması gerekmez. Bir örnek vermek gerekirse ... bir web sitesine güvenli bir şekilde bağlanmak için SSL kullanabilirsiniz. Kullandığınız SSL oturum anahtarı, elektronik olmayan biçimde hiçbir yerde depolanmaz ve bir paroladan türetilmez.
haha açıklığa kavuşturmak gerekirse, "fiziksel form" derken, kafamdan başka bir yeri kastediyorum - ama kafam da fiziksel olduğu için bu pek mantıklı gelmedi.
curiousguy
2011-09-28 09:03:50 UTC
view on stackexchange narkive permalink

Kriptografik bir protokolde: Doğrulanmış her mesajı tanınabilir yapın: iki mesaj aynı görünmemelidir

Bir genelleme / varyantı:

  • Birden çok dizeyi birleştirmeden önce dikkatli olun.
  • Anahtarları yeniden kullanmayın.
  • Hiçleri tekrar kullanmayın.

Bir kriptografik protokol çalıştırma, bir sır olmadan (anahtar veya nonce) taklit edilemeyen birçok mesaj değiştirilebilir. Bu mesajlar, bazı genel (imza) anahtarlarını bildiği için veya yalnızca kendisi ve gönderen bazı simetrik anahtarları veya nonce bildiği için alınan tarafından doğrulanabilir. Bu, bu mesajların değiştirilmediğinden emin olmanızı sağlar.

Ancak bu, bu mesajların protokolün aynı çalışması sırasında gönderilmesini sağlamaz : bir düşman ele geçirmiş olabilir bu mesajlar önceden veya protokolün eşzamanlı çalışması sırasında. Bir düşman, geçerli mesajları yakalamak ve bunları değiştirilmeden yeniden kullanmak için eşzamanlı birçok kriptografik protokol çalıştırması başlatabilir.

Mesajları akıllıca tekrar oynayarak, herhangi bir RNG'ye saldırmadan herhangi bir birincil anahtardan ödün vermeden bir protokole saldırmak mümkün olabilir. , herhangi bir şifre, vb.

Protokolün kimliği doğrulanmış her mesajını alıcı için açıkça farklı kılarak, değiştirilmemiş mesajları yeniden oynatma fırsatları azaltılır (ortadan kaldırılmaz).

Aslında, bir nonce'nin sır olması gerekmez, yalnızca bir kez kullanılması gerekir (belirli bir süre içinde, örneğin ilgili gizli anahtarın geçerliliği).
@PaŭloEbermann Bir nonce'nin pek çok kullanımı gizlilik gerektirmez, ancak bazı protokol formalizmleri, mesajların kimliğini doğrulamak için kullanılan * gizli * anahtarını bir anahtar yerine "nonce" olarak adlandırır, çünkü bir şifreleme anahtarı olarak kullanılmaz.
D.W.
2011-02-20 09:44:44 UTC
view on stackexchange narkive permalink

Güvenli olmayan anahtar uzunlukları kullanmayın.

Yeterince uzun bir anahtara sahip algoritmalar kullandığınızdan emin olun.

Simetrik anahtar şifrelemesi için, I ' d en az 80 bitlik bir anahtar önerin ve mümkünse 128 bitlik bir anahtar iyi bir fikirdir. 40 bitlik kripto kullanmayın; güvensizdir ve amatörler tarafından, sadece mümkün olan her anahtarı kapsamlı bir şekilde denemek suretiyle kolayca kırılır. 56 bit DES kullanmayın; kırmak önemsiz değildir, ancak DES'i kırmak adanmış saldırganların ulaşabileceği bir mesafededir. AES gibi 128 bitlik bir algoritma, 40 bitlik kriptodan kayda değer ölçüde yavaş değildir, bu nedenle bozuk kripto kullanmak için mazeretiniz yoktur.

Açık anahtarlı şifreleme için, anahtar uzunluğu önerileri algoritmaya bağlıdır ve gerekli güvenlik seviyesi. Ayrıca, anahtar boyutun artırılması performansa zarar verir, bu nedenle devasa aşırılık ekonomik değildir; bu nedenle, bu simetrik anahtar boyutlarının seçiminden biraz daha fazla düşünmeyi gerektirir. RSA, El Gamal veya Diffie-Hellman için, anahtarın mutlak minimum olarak en az 1024 bit olmasını öneririm; ancak 1024-bit anahtarlar, yakın vadede kırılabilir hale gelebilecek olanın sınırındadır ve genellikle modern kullanım için tavsiye edilmez, bu yüzden eğer mümkünse, 1536 veya hatta 2048-bit anahtarları tavsiye ederim. Eliptik eğri şifreleme için 160 bitlik anahtarlar yeterli görünür ve 224 bitlik anahtarlar daha iyidir. Simetrik ve açık anahtar boyutları arasında kabaca denklikler belirleyen yayınlanmış yönergelere de başvurabilirsiniz.

NIST, 2010 sonu itibariyle 1024 bit'ten fazla anahtar önermektedir: http://securitymusings.com/article/1587/algorithm-and-key-length-deprecation
Katılmadığım tek cümle: "Bu, bugünlerde daha az yaygın olan bir hata" "..." Şifreleme yok "ve" Kendi kripto paranı döndürme "sonrasında gördüğüm en yaygın kripto hatalarından biri.
@AviD, @nealmcb, geri bildiriminiz için teşekkürler. @AviD's yorumunu yansıtacak şekilde düzenledim. Bunu bir topluluk wiki yaptığımı unutmayın, bu nedenle önerileri iyileştirmek ve hataları düzeltmek için düzenlemekten çekinmeyin.
D.W.
2011-02-20 09:48:24 UTC
view on stackexchange narkive permalink

Aynı anahtarı her iki yönde de kullanmayın.

Ağ iletişimlerinde yaygın bir hata, iletişim için aynı anahtarı A-> B yönünde kullanmaktır. B-> A yönüne gelince. Bu kötü bir fikir, çünkü genellikle A'nın B'ye A'ya gönderdiği bir şeyi tekrar eden tekrar oynatma saldırılarını mümkün kılıyor.

En güvenli yaklaşım, her bir yön için bir tane olmak üzere iki bağımsız anahtar üzerinde uzlaşmaktır. Alternatif olarak, tek bir K anahtarıyla anlaşabilir, ardından bir yön için K1 = AES (K, 00..0) ve diğer yön için K2 = AES (K, 11..1) kullanabilirsiniz.

Veya her şifreleme için artırılmış bir SSC, güvenli oturum sayacınız olabilir (yarı çift yönlü iletişim içinde). Karşı tarafın son şifreli metni bloğunun bir sonraki blok için IV olarak kullanıldığı bir örnek bile gördüm, ancak bu bazı tuhaf saldırılara yol açabilir.
@owlstead, Evet, CBC modu ile birlikte sonraki blok için IV olarak şifreli metin bloğunun son bloğunu kullanmak, SSL üzerinde BEAST saldırısına yol açtı. Not: Bir SSC, iki kanalı ayırmak için çalışabilir, ancak buna dikkat etmeniz gerekir. Hem gönderme hem de alma için artırmanız gerekir (her yön için bir tane olmak üzere iki SSC kullanmak amacı geçersiz kılar). Ayrıca SSC, her iki tarafın da senkronize olmasını gerektirecek ve bazı ayarlarda sorunlu olabilecek paket düşüşlerine tolerans göstermeyecektir. Yalnızca iki bağımsız anahtar kullanmak daha kolay olabilir.
İlginç, bu şemayı şifreleme bloğunun son kısmıyla bir sonraki için IV olarak kullanan bazı hafıza kartlarını biliyorum. Ben bakarım. Teşekkürler D.W, tahminim bu konuda haklıydı.
Bu aynı zamanda Microsoft PPTP'yi biten bir Two time pad saldırısının kapısını da açar. PPTP'nin ilk sürümü, istemcide ve sunucuda aynı anahtarı kullandı
Shane Hansen
2012-09-08 21:55:43 UTC
view on stackexchange narkive permalink

Doğru modu kullanın

Aynı şekilde, güvenli olmak için kitaplık varsayılan ayarlarına güvenmeyin. Spesifik olarak, AES'yi uygulayan birçok kitaplık, FIPS 197'de açıklanan algoritmayı uygular; bu, ECB (Elektronik Kod Kitabı) modu olarak adlandırılır ve esasen aşağıdakilerin basit bir eşlemesidir:

  AES ] bayt, anahtar [32] bayt) -> şifreli metin [32] bayt  

çok güvenli değil. Muhakeme basittir, anahtar uzayındaki olası anahtarların sayısı oldukça büyükken, buradaki zayıf bağlantı mesajdaki entropi miktarıdır. Her zaman olduğu gibi, xkcd.com'un tanımladığımdan daha iyi olduğunu http://xkcd.com/257/

Temelde CBC (Cipher Block Chaining) gibi bir şey kullanmak çok önemlidir. şifreli metni [i] bir eşleme yapar:

  ciphertext [i] = SomeFunction (ciphertext [i-1], message [i], key)  

Sadece bu tür bir hatanın yapılmasının kolay olduğu birkaç dil kitaplığına işaret etmek için: http://golang.org/pkg/crypto/aes/, safça kullanılırsa, bir AES uygulaması sağlar. sonuç ECB modunda olur.

Pycrypto kitaplığı, yeni bir AES nesnesi oluştururken varsayılan olarak ECB moduna geçer.

OpenSSL, bunu doğru yapar. Her AES çağrısı, işlemin modu hakkında açıktır. Gerçekten en güvenli şey, IMO'nun kendi kendinize böyle düşük seviyeli kripto yapmamaya çalışmasıdır. Eğer mecbur kalırsanız, kırık cam üzerinde yürüyormuş gibi (dikkatlice) ilerleyin ve kullanıcılarınızın verilerini korumak için size güvendiklerinden emin olmaya çalışın.

Cevap için teşekkürler, Shane! Bir soru: Bu zaten diğer yanıt tarafından kapsanmış mı [Simetrik şifreleme için ECB ile bir blok şifresi kullanmayın] (http://security.stackexchange.com/a/2203/971)?
D.W.
2012-10-17 19:57:20 UTC
view on stackexchange narkive permalink

Aynı anahtarı birçok cihazda tekrar kullanmayın.

Bir kriptografik anahtarı ne kadar yaygın şekilde paylaşırsanız, onu tutma olasılığınız o kadar düşüktür gizli. Bazı konuşlandırılmış sistemler, sistemdeki her cihazda aynı simetrik anahtarı yeniden kullandı. Bununla ilgili sorun, er ya da geç, birinin anahtarı tek bir cihazdan çıkarması ve sonra diğer tüm cihazlara saldırabilmesidir. Öyleyse, bunu yapmayın.

Ayrıca bu blog makalesinde "Simetrik Şifreleme # 6 Yapmayın: Tek bir anahtarı birçok cihazda paylaşmayın" konusuna bakın. Matthew Green kredileri.

John Deters
2013-05-15 22:04:48 UTC
view on stackexchange narkive permalink

Anahtar bir algoritma tarafından genişletilirse, tek kullanımlık ped, tek kullanımlık ped değildir

"tek kullanımlık ped" (Vernam şifresi olarak da bilinir) tanımlayıcı sıklıkla yanlış uygulanır kırılmaz güvenlik talep etme girişiminde çeşitli kriptografik çözümler. Ancak tanımı gereği, bir Vernam şifresi ancak ve ancak bu koşulların üçü de karşılanırsa güvenlidir:

  • Anahtar malzeme gerçekten tahmin edilemez; VE
  • Anahtar materyal, düz metin ile aynı uzunluktadır; VE
  • Temel materyal asla tekrar kullanılmaz.

Bu koşulların herhangi bir ihlali, artık tek seferlik bir tuş şifresi olmadığı anlamına gelir.

Yapılan yaygın hata, kısa bir anahtarın bir algoritma ile uzatılmasıdır. Bu eylem, tahmin edilemezlik kuralını ihlal eder (anahtar uzunluk kuralını boşverin.) Bu yapıldığında, tek seferlik alan matematiksel olarak anahtar genişletme algoritmasına dönüştürülür. Kısa anahtarı rastgele baytlarla birleştirmek, yalnızca anahtar genişletme algoritmasını zorlamak için gereken arama alanını değiştirir. Benzer şekilde, "rastgele oluşturulmuş" baytların kullanılması, rastgele sayı üreteci algoritmasını güvenlik algoritmasına dönüştürür.

İşte basit bir örnek. Anahtar oluşturucu olarak kriptografik olarak güvenli bir işlev kullanan bir "tek kullanımlık ped" kullanarak şifreleyeceğim bir mesajım var. Gizli bir anahtar seçtim, ardından tekrar kullanılmamasını sağlamak için ona rastgele bir sayı ekledim. Anahtarı yeniden kullanmadığım için, bir mesajı diğerinden çıkararak şifreli metne saldırmanın bir yolu yok.

  düz metin: 1234567890123456789012345678901234567890 anahtar malzemesi: 757578fbf23ffa4d748e0800dd7c424a46feb0ccOTP işlevi (xor0ccOTP) ------ şifreli metin: 67412E83622DCE1B0C1E1A348B04D25872A8C85C  

Anahtar materyali, SHA-1 kullanılarak gizli şifremi genişletmek amacıyla (artı rasgele) hashing uygulayacak şekilde güvenli bir şekilde oluşturuldu. Ancak kullanılan germe algoritmasını * bilen herhangi bir saldırgan, SHA-1'e çeşitli girdiler deneyerek ve çıktıyı şifreli metinle XORlayarak ona saldırabilir. "OTP" anahtarını tahmin etmek artık kriptografik algoritmanın birleşik girişlerini tahmin etmekten daha zor değil. Bu özellik, hangi temel şifreleme algoritmasının seçildiğinden, hangi karmaşıklık ölçülerini içerdiğinden veya nasıl uygulandığından veya tohumlandığından bağımsız olarak geçerlidir.

Çok iyi bir anahtar genişletme algoritmanız olabilir. Ayrıca çok güvenli bir rastgele sayı üreticiniz de olabilir. Bununla birlikte, algoritmanız tanımı gereği tek seferlik bir blok değildir ve bu nedenle tek seferlik bir pedin kırılmaz özelliğine sahip değildir.

* Kerckhoff ilkesini uygulamak, saldırganın her zaman karar verebileceğini varsaymanız gerektiği anlamına gelir. kullanılan algoritmalar.

"Anahtarı tekrar kullanmadığım için, bir mesajı diğerinden çıkararak şifreli metne saldırmanın bir yolu yok." Düzenleyip diğer saldırıların mümkün olduğunu söyleyen bir metin ekler misiniz? ÖRNEK: iki zaman pedi, kötü protokol veya diğer önyargı (sırasıyla PPTP, WEP, RC4). Bilinemez bir meslekten olmayan kişi yazdıklarınızı yanlış okuyabilir ve OTP'nin kelimenin başka bir anlamıyla "mükemmel gizlilik" sunduğunu düşünebilir. Ayrıca, bu konuyu açtığınızdan, geçerli bir PNG / PRG anahtar sedyesinin ne olduğuna dair biraz bilgi vermeniz faydalı olacaktır.
Not: Bir OTP'de mesaj kimlik doğrulaması yoktur. OTP'de yapılan değişiklikler tespit edilmeyecek.
Not: * güvenli bir PRG *, OTP'ye benzer. İhmal edilebilir sonuçlarla tüm verimli istatistiksel testleri içeren ve bir PRG'nin her teorik istatistiksel testi karşılaması imkansızdır. "Kusursuz Gizlilik", mesajın boyutuyla eşleşecek kadar büyük bir OTP'nin güvenli bir şekilde iletilmesini gerektirdiğinden, bu güvenlik "rahatlatıcı" verimlilik için gereklidir. ÖRNEK: Tüm OTP iletimleri, sırrın güvenli bir şekilde iletilmesini gerektirir (ki bunun nasıl olduğu tanımlanmamıştır). Verileri ilk etapta göndermek için bu güvenli yöntemi kullanmak daha verimlidir.
İnsanları kırılmazlık konusunda tuhaf iddialarda bulunmaya sevk eden "benzerlik" ve Vernam şifresinin öngörülemezliğini kıran da bu "verimlilik" dir. OTP ile anahtar oluşturmanın, anahtar yönetiminin veya anahtar dağıtımının kolay veya pratik olduğunu kimse söylemedi - yukarıdakilerin hiçbiri değil. Matematiksel olarak mükemmel gizlilik vaadine rağmen, insanların hala diğer şifreleri kullanması o kadar zor ki. Hiçbir "anahtar germe" bu gerçeği değiştiremez.
Bitleri oluşturmak için "güvenli bir PRNG" kullanılabilir, ancak gerçekten güvenliyse, hala tüm dağıtım sorunlarına sahip olursunuz çünkü bunların nesillerini alıcının bilgisayarında kopyalayamazsınız - eğer yapabilseydiniz, bu durum anahtar olur, anahtar değil bitler.
Watson Ladd
2012-09-08 21:05:27 UTC
view on stackexchange narkive permalink

Standartlara Güvenmeyin.

Kriptografide pek çok standart vardır ve bazen bunları kullanmanız gerekir. Ancak standartları yazan kişilerin ihtiyaç duydukları kriptografiyi yeterince anladıklarını varsaymayın. Örneğin, EAX bir ağ standardında yeniden çalışıldı. EAX'ın bir güvenlik kanıtı vardır. Yeniden işlenmiş sürüm olmadı.

MD5 standarttır. Şimdi kırıldı. Çok sayıda tehlikeli özellik sayesinde çip ve PIN defalarca kırıldı. GPG, rahatlık için çok kısa olan DSA anahtarlarını hala desteklemektedir. SSL, kullanılmaması gereken seçeneklere sahiptir ve bunlardan kaçınmak için özen gerektirir.

Bu konuda ne yapılabilir? Dikkatli olmak, bilinen riskleri anlamak ve yenileri için araştırmaya ayak uydurmak.

MD5 bir standarttır, doğru. Ancak daha güncel bir standart olan SHA ile değiştirildi. Çoğu senaryo için, standartlara birçok nedenden dolayı uyulmalıdır. Birlikte çalışabilirlik çok büyük bir faktördür.
Bu çok yanıltıcı bir ifadedir. İfade, okuyucunun "standart OLMAYAN standartlara güvenmesi" gerektiği anlamına gelir, ki bu açıkça doğru değildir. Çoğu güvenlik standardı ancak kapsamlı gerçek dünya saha testlerinden sonra ortaya çıkar. Bu test, tek bir kuruluşun standart olmayan sistemlerinin güvenli olduğunu "kanıtlamak" için üretebileceğinden çok daha kapsamlı.
goodguys_activate
2013-05-20 20:47:19 UTC
view on stackexchange narkive permalink

Disk şifrelemede OTP veya akış şifresi kullanmayın

Örnek 1

İki dosyanın kaydedildiğini varsayalım bir akış şifresi / OTP kullanarak. Dosya küçük bir düzenlemeden sonra yeniden kaydedilirse, saldırgan yalnızca belirli bitlerin değiştirildiğini görebilir ve belge hakkında bilgi çıkarabilir. ("Sevgili Ahmet" i "Sevgili Alice" olarak değiştirdiğinizi hayal edin).

Örnek 2

Çıktıda bütünlük yoktur: bir saldırgan Şifreli metni değiştirin ve verileri yalnızca XORing yaparak verilerin içeriğini değiştirin.

Çıkarın: Şifreli metinde yapılan değişiklikler tespit edilmez ve düz metin üzerinde tahmin edilebilir bir etkiye sahiptir.

Çözüm

Bu durumlar için mesaj bütünlüğü kontrollerini içeren bir Blok şifresi kullanın

goodguys_activate
2013-05-20 21:08:44 UTC
view on stackexchange narkive permalink

Asla Tek Kullanımlık Tuş Takımı (OTP) veya akış şifreleme anahtarını birden fazla kullanmayın

İki kez uygulanan OTP, "mükemmel gizlilik" ile şifrelenen verilerin şifresinin çözüleceği ve açıkta. Bunun nedeni verilerin iki kez XOR'lanmasıdır.

Örnek

Bir OTP'nin / veya aynı anahtara sahip akışın yeniden kullanıldığını varsayın.

Bir saldırgan çok fazla veri toplar bir istemciden bir sunucuya gönderilir ve iki paket birbirinin şifresini çözene kadar (veya oradaki alt küme) iki paketten oluşan bir kümeyi XORs.

ASCII kodlamasında yeterince fazlalık vardır, bu da yeterli şifreli metin verildiğinde orijinal mesajların (gizli OTP anahtarı ile birlikte) kodunun çözülebileceği anlamına gelir.

Gerçek dünya örnekleri

  • Ruslar tarafından kullanılan bir OTP örneği için Project Verona (1941-46) ve daha sonra ABD istihbarat teşkilatı tarafından şifresi çözüldü

  • Microsoft'un PPTPv1'i hem istemci hem de sunucu aynı anahtarı kullanarak verileri şifreler.

  • WEP yeniden kullanır aynı anahtar 2 ^ 24 paket gönderildiğinde veya bir NIC kartı sıfırlandığında. İlk sorun, IV'ün 24 bit uzunluğunda olmasından kaynaklanır ve 16 Milyon kare iletildikten sonra iki zaman pedi yaratılır. İkinci sorun, bir güç döngüsünden sonra IV'ün sıfıra sıfırlanarak iki zaman aralığı oluşturduğu donanım uygulamalarında ortaya çıkar. IV net bir şekilde gönderildiği için bu sorunu görmek kolaydır.

Öneriler

  • Her oturum için yeni bir anahtar oluşturulmalıdır (ör. TLS).

  • İstemci, sunucu ve sunucu ile bir OTP (veya PRG ile akış şifresi) kullanmalıdır. istemciye veri şifrelerken farklı bir anahtar kullanmalıdır

  • Çok sayıda anahtar oluşturmak yerine, tek bir anahtarı uzun bir akış halinde genişletmek mümkündür PRG kullanarak (PRG'ye güvendiğinizi varsayarak) ve bu genişlemenin her bir bölümünü anahtar olarak kullanın.

  • Tüm PRG'lerin artış modunda çalışmak üzere tasarlanmadığını ve rastgele giriş gerekebileceğini bilin. (RC4'te bu sorun artış modunda var)

goodguys_activate
2013-05-20 21:26:00 UTC
view on stackexchange narkive permalink

RC4'ü kullanmayın

RC4, 1987'de bir akış şifresi olarak kullanılmak üzere tasarlanmıştır. HTTPS ve WEP'de kullanılır.

Zayıf yönler vardır

  1. İlk çıktıda sapma vardır: Pr [2. bayt = 0] = 2/256
  2. Sıfıra eşit on altı bit olasılığı 1/256 ^ 2 + 1/256 ^ 3'tür. Bu, birkaç GB veri şifrelendikten sonra gerçekleşir.
  3. Yalnızca IV'ün değiştiği ancak anahtarın aynı kaldığı ilgili anahtar saldırılarına karşı savunmasızdır.

Çıkarın RC4 kullanmanız gerekiyorsa, önyargılı oldukları için ilk 256 baytı dikkate almayın. RC4'ü Gigs veri için kullanırsanız, RC4'teki önyargı, önceki tüm şifrelenmiş verilerin saldırılarına izin verecektir.

goodguys_activate
2013-05-20 21:49:46 UTC
view on stackexchange narkive permalink

Donanım veya Yazılımda uygun şekilde çalışan modern akış işlemcileri kullanın

Tüm akış şifreleri, donanım veya yazılımda uygulanacak şekilde tasarlanmamıştır. Doğrusal geribildirim kaydırma yazmacı (LFSR), kolayca kırılan, yaygın olarak kullanılan bir donanım şifresinin bir örneğidir.

LFSR şu uygulamalarda kullanılır:

  • DVD şifreleme (CSS olarak da bilinir) 2 LFSR
  • GSM şifreleme (A5 / 1.2) 3 LSFR
  • Bluetooth (E0): 4 LFSR

Yukarıdakiler için donanım yaygın olarak kullanılmaktadır ve bu nedenle güncellenmesi veya modern standartlara getirilmesi zordur. Yukarıdakilerin tümü kötü bir şekilde bozuktur ve güvenli iletişim için güvenilmemelidir.

Saldırı:

Şifreleme sırasında anahtar iki bölüme ayrıldığından ( 17 bit ve 25 bit) ve bu bitler aynı şifre metnini şifrelemek için kullanılır, MPEG formatı bilgisini kullanmak ve 25 bitlik anahtarın ne olduğunu tahmin etmek için 17 bitlik bir anahtara kaba kuvvet uygulamak mümkündür.

Bu pek yeni değil, ancak FOSS'u bulmak kolay, bu sorunu gösteriyor.

Çözüm:

eStream projesi (2008'de ) kullanılması gereken nitelikli 5 akış şifresi. Dikkate değer bir fark, IV ile bir Anahtar kullanmak yerine, şifrelerin bir Anahtar, bir nonce ve bir sayaç kullanmasıdır. Salsa20 bu şekilde çalışır ve hem donanım hem de yazılımda kolayca kullanılmak üzere tasarlanmıştır. Özellikle, x86 SSE2 komut setine dahil edilmiştir.

Bir kenara

Modern şifreler yalnızca daha güvenli değil, aynı zamanda daha hızlıdır:

  PRG Hızı (MB / sn) RC4 126 (eski) Salsa20 / 12 643 (modern) Sosemaunk 727 (modern)  
goodguys_activate
2013-05-23 09:42:28 UTC
view on stackexchange narkive permalink

Yalnızca mesaj uzantısı saldırılarına karşı savunmasız olmayan MAC'leri kullanın

MAC, belirli bir düzeyin mesaj bütünlüğünü (hiçbir değişiklik, vb.) sağlayan bir karma koddur. Metin. Pek çok uygulama ve yayınlanmış standart, bir MAC'yi, MAC'a ek veri ekleyen bir saldırgandan korumada başarısız olur.

Bunun çözümü, MAC uygulamasının ikinci (farklı) bir anahtar kullanması ve son çıktıyı yeniden şifrelemesidir.

ECBC ve NMAC, şifreyi doğru şekilde engelleyen şifrelere örneklerdir. mesaj uzantısı saldırısı.

Çözüm:

  • Ham CBC yerine Şifreli CBC (ECBC) kullanın
  • cascade
yerine NMAC kullanın


Bu Soru-Cevap, otomatik olarak İngilizce dilinden çevrilmiştir.Orijinal içerik, dağıtıldığı cc by-sa 2.0 lisansı için teşekkür ettiğimiz stackexchange'ta mevcuttur.
Loading...