it-swarm-tr.com

Öğrenilen dersler ve şifreleme ve kriptoloji ile ilgili kavram yanılgıları

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

Bu sorunun amacı, verilen bir algoritma veya API ile değil ne yapılacağını tanımlamak ve listelemektir. Bu şekilde başkalarının deneyimlerinden öğrenebilir 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. Mümkün olan en iyi şekilde, yukarıdaki # 2 ve # 3 ile ilgili referanslar sağlayın.
68
goodguys_activate

Kendi kripto paralarınızı atmayın.

Kendi şifreleme algoritmanızı veya protokolünüzü icat etmeyin; bu son derece hata eğilimli. Bruce Schneier'in dediği gibi,

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

Kripto algoritmaları çok karmaşıktır ve güvenli olduklarından emin olmak için yoğun araştırmalara ihtiyaç duyarlar; kendinizinkini icat ederseniz, bunu elde edemezsiniz ve farkına varmadan güvensiz bir şeyle sonuçlanmak çok kolaydır.

Bunun yerine standart bir şifreleme algoritması ve protokolü kullanın. Oranlar, bir başkasının sorununuzu daha önce görmüş ve bu amaç için uygun bir algoritma tasarlamış olmasıdır.

En iyi durumunuz, üst düzey iyi denetlenmiş bir şema kullanmaktır: iletişim güvenliği için TLS (veya SSL) kullanın; hareketsiz veriler için GPG (veya PGP) kullanın. Bunu yapamıyorsanız, cryptlib , GPGME, Keyczar veya NaCL , OpenSSL, CryptoAPI, JCE, vb. Gibi düşük seviyeli bir tane yerine. Bu öneri için Nate Lawson'a teşekkürler.

76
D.W.

Mesaj kimlik doğrulaması olmadan şifreleme kullanmayın

Verileri kimlik doğrulaması yapmadan şifrelemek çok yaygın bir hatadır.

Örnek: Geliştirici bir mesajı gizli tutmak ister, bu nedenle mesajı AES-CBC moduyla şifreler. Hata: Bu, aktif saldırılar, tekrar saldırıları, reaksiyon saldırıları, vb. Varlığında 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, ileti kimlik doğrulaması eklemektir.

Bu hata, ASP.NET , XML kimlik doğrulaması olmadan şifreleme kullanan konuşlandırılmış sistemlerde ciddi güvenlik açıklarına yol açtı. şifreleme , Amazon EC2 , JavaServer Yüzleri, Ruby, OWASP ESAPI , IPSEC , WEP , tekrar ASP.NET ve SSH2 Bu listede bir sonraki olmak istemiyorsun.

Bu sorunları önlemek için, şifrelemeyi her uyguladığınızda ileti kimlik doğrulaması kullanmanız gerekir. Bunun nasıl yapılacağı konusunda iki seçeneğiniz var:

  • Muhtemelen en basit çözüm, kimlik doğrulamalı şifreleme , örn., GCM, CWC, EAX, CCM, OCB sağlayan bir şifreleme şeması kullanmaktır. (Ayrıca bkz: 1 .) Kimliği doğrulanmış şifreleme şeması bunu sizin için halleder, bu yüzden bunu düşünmenize gerek yoktur.

  • Alternatif olarak, aşağıdaki gibi kendi mesaj kimlik doğrulamanızı uygulayabilirsiniz. İlk olarak, mesajı uygun bir simetrik anahtar şifreleme şeması (örn., AES-CBC) kullanarak şifreleyin. Ardından, tüm şifreleme metnini alın (şifre çözme için gereken IV'ler, kopyalar veya diğer değerler dahil), bir ileti kimlik doğrulama kodu uygulayın (örn. AES-CMAC, SHA1-HMAC, SHA256-HMAC) 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 şifreleme-sonra-kimlik doğrulaması yapısı olarak bilinir. (Ayrıca bkz: 1 , 2 .) Bu da iyi çalışıyor, ancak sizden biraz daha fazla bakım gerektiriyor.

47
D.W.

Karma işleminden önce birden fazla dizeyi birleştirirken dikkatli olun.

Bazen gördüğüm bir hata: İnsanlar S ve T dizelerinin bir karmasını istiyorlar. Tek bir S dizisi elde etmek için onları birleştiriyorlar, sonra H (S || T) elde etmek için onları birleştiriyorlar. Bu kusurlu.

Sorun: Birleştirme, iki dize arasındaki sınırı belirsiz kılar. Örnek: builtin || securely = built || insecurely. Başka bir deyişle, H (S || T) karması, S ve T dizesini benzersiz bir şekilde tanımlamaz. Bu nedenle, saldırgan karmayı değiştirmeden iki dize arasındaki sınırı değiştirebilir. Örneğin, Alice builtin ve securely iki dizesini göndermek isterse, saldırgan bunları geçersiz kılmadan built ve insecurely iki dizeye dönüştürebilir karması.

Dizelerin birleştirilmesine dijital imza veya ileti kimlik doğrulama kodu uygulanırken de benzer sorunlar geçerlidir.

Düzeltme: düz birleştirme yerine, net bir şekilde kodu çözülebilir bazı kodlama kullanın. Örneğin, H (S || T) hesaplamak yerine H (uzunluk (S) || S || T) hesaplayabilirsiniz; burada uzunluk (S), bayt cinsinden S uzunluğunu gösteren 32 bitlik bir değerdir. Veya başka bir olasılık H (H (S) || H (T)), hatta H (H (S) || T) kullanmaktır.

Bu kusurun gerçek dünyadaki bir örneği için bkz. Amazon Web Services'daki bu kusur veya Flickr'daki bu kusur [pdf].

36
D.W.

Nonces veya IV'leri tekrar kullanmayın

Birçok çalışma modu bir IV (Başlatma Vektörü) gerektirir. Aynı değeri bir IV için asla iki kez tekrar kullanmamalısınız; bunu yapmak tüm güvenlik garantilerini iptal edebilir ve yıkıcı bir güvenlik ihlaline neden olabilir.

  • CTR modu veya OFB modu gibi akış şifreleme çalışma modları için IV'ü tekrar kullanmak bir güvenlik felaketidir. Şifreli mesajların önemsiz bir şekilde kurtarılmasına neden olabilir.

  • CBC modu gibi diğer çalışma modları için, IV'ü tekrar kullanmak 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. Bunu nasıl doğru yapacağınızı merak ediyorsanız, NIST spesifikasyon , blok şifreleme çalışma modlarının doğru bir şekilde nasıl kullanılacağına dair ayrıntılı belgeler sağlar.

Tarsnap projesi bu tuzağa iyi bir örnek sunuyor. Tarsnap, yedekleme verilerini parçalara bölerek ve daha sonra her bir parçayı TO 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ı sağladı.

Bu nasıl oldu? Tarsnap kodunu basitleştirmek için - ve hata potansiyelini azaltma umuduyla - Colin Percival, AES-CTR kodunu Tarsnap kaynak kodunda yeni bir dosyaya (ref/crypto/crypto_aesctr.c "" yeniden düzenleme "fırsatı buldu. ) ve bu rutinlerden yararlanmak için AES-TO'nun kullanıldığı mevcut yerleri değiştirdi. Yeni kod şöyle görünür:

/* Verileri şifreleyin. */
 - aes_ctr (& encr_aes-> anahtar, encr_aes-> nonce ++, buf, len, 
 - filebuf + CRYPTO_FILE_HLEN); 
 + if ((akış = 
 + crypto_aesctr_init (& encr_aes-> anahtar, encr_aes-> nonce)) == NULL) 
 + err0 git; 
 + 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 ve sonuç olarak aynı nonce değeri tekrar tekrar kullanıldı . Özellikle, her bir yığın şifrelendikten sonra TO nonce değeri artırılmaz. (Her 16 bayt veri işlendikten sonra TO sayacı doğru bir ş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 şu şekilde açıklanır: http: //www.daemonology. net/blog/2011-01-18-tarsnap kritik güvenlik-bug.html

29
Alex Holst

Rastgele sayı üreteçlerini yeterli entropiye sahip olduğunuzdan emin olun.

Anahtar oluşturma, IV/nonce seçilmesi vb. İşlemler için kripto gücü olan sahte sayı üreteçleri kullandığınızdan emin olun. Rand(), random(), drand48() kullanmayın , vb.

Psödondom sayı üreticisini yeterli entropi ile tohumladığınızdan emin olun. Günün saatiyle tohumlama; bu tahmin edilebilir.

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

Gerçek dünya örneği: bkz. Netscape tarayıcısının ilk sürümlerindeki bu kusur , bir saldırganın SSL'yi kırmasına izin verdi.

29
D.W.

Simetrik şifreleme için ECB'li bir blok şifreleme kullanmayın

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

ECB modunun şifrelenmemiş koda nasıl yol açtığı konusunda post ve çok benzer bir Microsoft KB makalesi .

Ayrıca bakınız bu benzer yazı from Kale

Düz metin mesajı:

alt text

ECB moduyla şifrelenen aynı mesaj (hangi şifreyi kullandığınız önemli değildir): alt text

CBC modunu kullanarak aynı mesajı EXACT (tekrar, hangi şifreyi kullandığınız önemli değildir): alt text

Yanlış yol

public static string Encrypt(string toEncrypt, string key, bool useHashing)
{

byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);
byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

if (useHashing)
    keyArray = new MD5CryptoServiceProvider().ComputeHash(keyArray);

var tdes = new TripleDESCryptoServiceProvider() 
    { Key = keyArray, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 };

ICryptoTransform cTransform = tdes.CreateEncryptor();
byte[] resultArray = cTransform.TransformFinalBlock(
    toEncryptArray, 0, toEncryptArray.Length);

return Convert.ToBase64String(resultArray, 0, resultArray.Length);
}

Hata aşağıdaki satırda

{Key = keyArray, Mod = CipherMode.ECB , Dolgu = PaddingMode.PKCS7};


Doğru yol

Microsoft iyi insanlar bana yukarıda bağlantılı KB makaleyi düzeltmek için aşağıdaki kodu gönderdi. Bu durumda başvurulmaktadır # 111021973179005

Bu örnek kod, verileri şifrelemek için AES kullanıyor ve AES şifrelemesinin anahtarı SHA256 tarafından oluşturulan karma kod. 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 MSDN Magazine'deki http://msdn.Microsoft.com/en-us/magazine/cc164055.aspx adresindeki “Yeni Gelişmiş Şifreleme Standardı ile Verilerinizi Güvende Tutun” başlıklı makaleye bakın. .

SHA, Güvenli Karma Algoritmasıdır. SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512) önerilmektedir. .NET Framework'teki Karma Değerler 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ışma modunun varsayılan değeri CBC'dir. CBC, Şifre Bloğu Zincirleme modudur. Geri bildirim sağlar. Her düz metin bloğu şifrelenmeden önce, bir önceki bloğun şifre metni ile bitwise exclusive OR işlemi) birleştirilir. Bu, düz metin birçok özdeş blok içeriyor olsa bile, başlatma vektörü, ilk düz metin bloğu ile bitwise exclusive OR işlemi, blok şifrelenmeden önce birleştirilir.) Şifreleme metin bloğunun tek bir bitiyle birleştirilir. Ayrıca, düz metin bloğu da karıştırılır.Ayrıca, sonraki blokta, orijinal karıştırılmış bit ile aynı konumda biraz karıştırılı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.

// This function is used for encrypting the data with key and iv.
byte[] Encrypt(byte[] data, byte[] key, byte[] iv)
{
    // Create an AESCryptoProvider.
    using (var aesCryptoProvider = new AesCryptoServiceProvider())
    {
        // Initialize the AESCryptoProvider with key and iv.
        aesCryptoProvider.KeySize = key.Length * 8;
        aesCryptoProvider.IV = iv;
        aesCryptoProvider.Key = key;

        // Create encryptor from the AESCryptoProvider.
        using (ICryptoTransform encryptor = aesCryptoProvider.CreateEncryptor())
        {
            // Create memory stream to store the encrypted data.
            using (MemoryStream stream = new MemoryStream())
            {
                // Create a CryptoStream to encrypt the data.
                using (CryptoStream cryptoStream = new CryptoStream(stream, encryptor, CryptoStreamMode.Write))
                    // Encrypt the data.
                    cryptoStream.Write(data, 0, data.Length);

                // return the encrypted data.
                return stream.ToArray();
            }
        }
    }
}

// This function is used for decrypting the data with key and iv.
byte[] Decrypt(byte[] data, byte[] key, byte[] iv)
{
    // Create an AESCryptoServiceProvider.
    using (var aesCryptoProvider = new AesCryptoServiceProvider())
    {
        // Initialize the AESCryptoServiceProvier with key and iv.
        aesCryptoProvider.KeySize = key.Length * 8;
        aesCryptoProvider.IV = iv;
        aesCryptoProvider.Key = key;

        // Create decryptor from the AESCryptoServiceProvider.
        using (ICryptoTransform decryptor = aesCryptoProvider.CreateDecryptor())
        {
            // Create a memory stream including the encrypted data.
            using (MemoryStream stream = new MemoryStream(data))
            {
                // Create a CryptoStream to decrypt the encrypted data.
                using (CryptoStream cryptoStream = new CryptoStream(stream, decryptor, CryptoStreamMode.Read))
                {
                    // Create a byte buffer array.
                    byte[] readData = new byte[1024];
                    int readDataCount = 0;

                    // Create a memory stream to store the decrypted data.
                    using (MemoryStream resultStream = new MemoryStream())
                    {
                        do
                        {
                            // Decrypt the data and write the data into readData buffer array.
                           readDataCount = cryptoStream.Read(readData, 0, readData.Length);
                            // Write the decrypted data to resultStream.
                            resultStream.Write(readData, 0, readDataCount);
                        }
                        // Check whether there is any more encrypted data in stream.
                        while (readDataCount > 0);
                        // Return the decrypted data.
                        return resultStream.ToArray();
                    }
                }
            }
        }
    }
}



// This function is used for generating a valid key binary with UTF8 encoding and SHA256 hash algorithm.
byte[] GetKey(string key)
{
    // Create SHA256 hash algorithm class.
    using (SHA256Managed sha256 = new SHA256Managed())

    // Decode the string key to binary and compute the hash binary of the key.
    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önetim Sınıfı

· CryptoStream Sınıfı

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

· Şifreleme Hizmetleri

· . NET Framework Şifreleme Modeli

· Basit Şifreleme Kılavuz

· Sırlar Olmadan Şifreleme

20
goodguys_activate

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 fazla amaç için tekrar kullanılmamalıdır; çeşitli ince saldırılara neden olabilir.

Örneğin, bir RSA özel/genel anahtar çiftiniz varsa, hem şifreleme (genel anahtarla şifreleme, özel anahtarla şifre çözme) hem de imzalama (özel anahtarla imzalama, genel anahtarla doğrulama) için kullanmamalısınız. ): tek bir amaç seçin ve sadece 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 şifreleme ile şifreleme için bir anahtar ve mesaj kimlik doğrulaması için ayrı bir bağımsız anahtar kullanmalısınız. Her iki amaç için aynı anahtarı tekrar kullanmayın.

20
D.W.

Kerckhoffs'in prensibi: Anahtar dışında sistem hakkında her şey halka açık bir bilgi olsa bile bir şifreleme sistemi güvenli olmalıdır

Yanlış bir örnek: LANMAN karmaları

Kimse algoritmayı bilmiyorsa, LANMAN karmalarını bulmak zor olurdu, ancak algoritma bilindikten sonra çatlamak çok önemsizdir.

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ş olarak doldurulmuştur
  3. “Sabit uzunluklu” parola iki yedi baytlık yarıya bölünür.
  4. Bu değerler, her 7 baytlık yarıdan bir tane olmak üzere iki DES anahtar) oluşturmak için kullanılır
  5. İki anahtarın her biri, ASCII “KGS! @ # $%” Dizesini DES-şifrelemek için kullanılır, bu da iki adet 8 baytlık şifreli metin değerlerine neden olur.
  6. Bu iki şifreli metin değeri, LM karması olan 16 baytlık bir değer oluşturmak üzere birleştirilir

Artık bu gerçeklerin şifreleme metnini bildiğiniz için, şifreleme metnini, parola olabileceği sınırlı sayıda karakterle sonuçlanan büyük harf olduğunu bildiğiniz iki şifre metnine kolayca ayırabilirsiniz.

Doğru örnek: AES şifrelemesi

  • Bilinen algoritma
  • Teknoloji ile ölçeklendirir. Daha fazla şifreleme isteğine ihtiyaç duyduğunuzda anahtar boyutunu büyütün
17
Chris Dale

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

Birçok sistemde yaygın bir zayıflık, şifreleme/şifre çözme anahtarı olarak bir parola veya parola veya bir parola veya parola karması kullanmaktır. Sorun, bunun çevrimdışı anahtar arama saldırılarına karşı oldukça duyarlı olma eğiliminde olmasıdır. Çoğu kullanıcı bu tür saldırılara karşı koymak için yeterli entropi içermeyen parolalar seçer.

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

Ancak, bir parolaya/parolaya dayalı bir tane kullanmanız gerekiyorsa, kapsamlı anahtar aramayı yavaşlatmak için uygun bir şema kullanın. Yinelemeli karma işlem kullanan PBKDF2 öneririm (H(H(H(....H(password)...)))) sözlük aramayı yavaşlat. Bu işlemin anahtar üretmek için kullanıcının makinesinde 100 ms sürmesine neden olacak kadar çok yineleme kullanacak şekilde düzenleyin.

13
D.W.

Şifreleme protokolünde: Kimliği doğrulanan her mesajı tanınabilir yapın: hiçbir iki mesaj aynı görünmemelidir

Bir genelleme/varyant:

  • Birden çok dizeyi birleştirirken, karma işleminden önce dikkatli olun.
  • Anahtarları tekrar kullanmayın.
  • Nonce'leri tekrar kullanmayın.

Bir kriptografik protokol çalışması sırasında, bir sır (anahtar veya nonce) olmadan taklit edilemeyen birçok mesaj değiştirilebilir. Bu iletiler, bazı genel (imza) anahtarları bildiği veya yalnızca kendisi ve gönderenin bazı simetrik anahtar veya nonce bildiği için alınanlar tarafından doğrulanabilir. Bu, bu iletilerin değiştirilmediğinden emin olur.

Ancak bu , bu mesajların protokolün aynı çalışması sırasında yayıldığından emin değildir: bir düşman bu mesajları daha önce veya bir protokolün eşzamanlı çalışması. Bir rakip, geçerli mesajları yakalamak ve değiştirilmeden yeniden kullanmak için bir şifreleme protokolünün birçok eşzamanlı çalışmasını başlatabilir.

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

Protokolün kimliği doğrulanmış her mesajını alıcı için açıkça farklı hale getirerek, değiştirilmemiş mesajları tekrar dinleme fırsatları azaltılır (elenmez).

13
curiousguy

Güvenli olmayan anahtar uzunlukları kullanmayın.

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

Simetrik anahtar şifrelemesi için en az 80 bit anahtar öneririm ve mümkünse 128 bit anahtar iyi bir fikirdir. 40 bit kripto kullanmayın; güvenli değil ve amatörler tarafından kolayca kırılabilir, sadece mümkün olan her anahtarı kapsamlı bir şekilde deneyerek. 56 bit DES kullanmayın; kırılması önemsiz değildir, ancak DES'i kırmak için adanmış saldırganların erişimindedir. 128 bitlik bir algoritma, AES gibi, 40 bitlik kriptodan oldukça yavaş değildir, bu yüzden crummy kripto kullanmak için mazeretiniz yoktur.

Ortak anahtar şifrelemesi için, anahtar uzunluğu önerileri algoritmaya ve gerekli güvenlik düzeyine bağlıdır. Ayrıca, anahtar boyutunun arttırılması performansa zarar verir, bu nedenle aşırı aşırı doldurma 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ı tavsiye ederim; Bununla birlikte, 1024 bitlik anahtarlar, yakın vadede kırılabilir hale gelebilecek olanın kenarındadır ve genellikle modern kullanım için önerilmez, bu nedenle mümkünse 1536 veya hatta 2048 bitlik anahtarlar öneririm. Eliptik eğri şifreleme için 160 bit anahtarlar yeterli görünür ve 224 bit anahtarlar daha iyidir. simetrik ve ortak anahtar boyutları arasında kabaca eşdeğerlikler belirleyen yayınlanmış yönergelere de başvurabilirsiniz.

8
D.W.

Her iki yönde de aynı anahtarı kullanmayın.

Ağ iletişiminde yaygın bir hata, A-> B yönünde iletişim için B-> A yönünde olduğu gibi aynı anahtarı kullanmaktır. Bu kötü bir fikirdir, çünkü A'ya B'ye gönderilen A'yı tekrar A'ya tekrar eden tekrar saldırılarına izin verir.

En güvenli yaklaşım, her yön için bir tane olmak üzere iki bağımsız anahtar üzerinde pazarlık etmektir. Alternatif olarak, tek bir anahtar K ile 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.

8
D.W.

Anahtar bir algoritma tarafından uzatılırsa, bir defalık ped bir defalık ped değildir

"Bir kerelik ped" (Vernam şifresi olarak da bilinir) tanımlayıcısı, kırılmaz güvenlik talebinde bulunmak amacıyla çeşitli şifreleme çözümlerine sıklıkla yanlış uygulanır. Ancak tanım gereği, bir Vernam şifresi yalnızca bu koşulların üçü de karşılandığında güvenlidir:

  • Anahtar malzeme gerçekten öngörülemez; VE
  • Anahtar malzeme düz metinle aynı uzunluktadır; VE
  • Anahtar malzeme asla tekrar kullanılmaz.

Bu koşulların herhangi bir şekilde ihlal edilmesi, artık bir kerelik bir pad şifresi olmadığı anlamına gelir.

Sık yapılan hata, bir algoritmanın kısa bir anahtarın uzatılmış olmasıdır. Bu eylem, öngörülemezlik kuralını ihlal eder (anahtar uzunluk kuralını boş verin.) Bu yapıldıktan sonra, tek seferlik ped matematiksel olarak anahtar germe algoritmasına dönüştürülür. Kısa anahtarı rastgele baytlarla birleştirmek, yalnızca anahtar germe algoritmasını kaba kuvvetle zorlamak için gereken arama alanını değiştirir. Benzer şekilde, "rastgele oluşturulmuş" baytların kullanılması rasgele sayı üreteci algoritmasını güvenlik algoritmasına dönüştürür.

İşte basit bir örnek. Bir anahtar üreteci olarak kriptografik olarak güvenli bir işlev kullanan bir "bir kerelik pad" kullanarak şifreleyecek bir mesaj var. Gizli bir anahtar seçtim, sonra tekrar kullanılmayacağından emin olmak için rastgele bir sayı ekledim. Anahtarı tekrar kullanmadığım için, bir mesajı diğerinden çıkararak şifre metnine saldırmanın bir yolu yoktur.

          plaintext : 1234567890123456789012345678901234567890
       key material : 757578fbf23ffa4d748e0800dd7c424a46feb0cc
OTP function (xor)  : ----------
         ciphertext : 67412E83622DCE1B0C1E1A348B04D25872A8C85C

Anahtar malzeme, uzatmak için gizli şifremi (artı rastgele) hash etmek için SHA-1 kullanılarak güvenli bir şekilde oluşturuldu. Ancak kullanılan germe algoritmasını * bilen herhangi bir saldırgan SHA-1'dir ve SHA-1'e çeşitli girişleri deneyerek ve çıktıyı şifreleme metniyle XORing yaparak ona saldırabilir. "OTP" anahtarını tahmin etmek artık şifreli algoritma için birleştirilmiş girdileri tahmin etmekten daha zor değil. Bu özellik, hangi temel şifreleme algoritmasının seçildiğine, hangi karmaşıklık ölçütlerine sahip olduğuna veya nasıl uygulandığına veya tohumlandığına bakılmaksızın doğru kalır.

Çok iyi bir anahtar germe algoritmanız olabilir. Ayrıca çok güvenli bir rastgele sayı üreteciniz olabilir. Bununla birlikte, algoritmanız tanım gereği bir defalık ped değildir ve bu nedenle bir defalık pedin kırılmaz özelliğine sahip değildir.

* Kerckhoff ilkesinin uygulanması, saldırganın her zaman kullanılan algoritmaları belirleyebileceğini varsaymanız gerektiği anlamına gelir.

3
John Deters

Doğru modu kullanın

Aynı şekilde, güvenli olması için kitaplık varsayılan ayarlarına güvenmeyin. Özellikle, AES uygulayan birçok kütüphane, FIPS 197, ECB (Elektronik Kod Kitabı) modu olarak adlandırılan ve aslında aşağıdakilerin basit bir eşlemesi olan) algoritmayı uygular:

AES(plaintext [32]byte, key [32]byte) -> ciphertext [32]byte

çok güvensizdir. Mantık basittir, anahtar alanındaki olası tuşların sayısı oldukça büyük olsa da, buradaki zayıf bağlantı mesajdaki entropi miktarıdır. Her zaman olduğu gibi, xkcd.com açıkladığı gibi ben daha iyidir http://xkcd.com/257/

Temelde şifre metnini [i] bir harita yapan CBC (Şifre Bloğu Zinciri) gibi bir şey kullanmak çok önemlidir:

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

Sadece bu tür bir hatanın kolayca yapılabileceği birkaç dil kütüphanesine dikkat çekmek için: http://golang.org/pkg/crypto/aes/ saf olarak kullanıldığında AES uygulaması sağlar ECB modunda sonuçlanır.

Yeni bir AES nesnesi oluştururken pycrypto kütüphanesi varsayılan olarak ECB moduna geçer.

OpenSSL, bunu doğru yapıyor. Her AES çağrısı çalışma şekli hakkında açıktır. Gerçekten en güvenli şey IMO, kendiniz gibi düşük seviye kripto yapmamaya çalışmaktır. Zorlanıyorsanız, kırık camın üzerinde yürüyormuş gibi ilerleyin (dikkatlice) ve kullanıcılarınızın verilerini korumak için size güvenmelerini haklı gösterdiklerinden emin olun.

3
Shane Hansen

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

Bir şifreleme anahtarını ne kadar geniş bir şekilde paylaşırsanız, onu gizli tutma olasılığınız o kadar az olur. Bazı konuşlandırılmış sistemler, sistemdeki her aygıtta aynı simetrik anahtarı yeniden kullanmıştır. Bununla ilgili sorun, er ya da geç, birinin anahtarı tek bir cihazdan çıkaracağı ve daha sonra diğer tüm cihazlara saldırabileceği. Yani, bunu yapma.

Ayrıca bu blog makalesi içindeki "Simetrik Şifreleme Yapma # 6: Tek bir anahtarı birçok cihazda paylaşma" konusuna bakın. Matthew Green'e verilen krediler.

3
D.W.

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

Örnek 1

Bir akış şifresi/OTP kullanılarak iki dosyanın kaydedildiğini varsayalım. Küçük bir düzenlemeden sonra dosya kaydedilirse, saldırgan yalnızca belirli bitlerin değiştirildiğini görebilir ve belge hakkında bilgi çıkarabilir. (Selamlama "Sevgili Bob" u "Sevgili Alice" olarak değiştirmeyi düşünün).

Örnek 2

Çıktıda herhangi bir bütünlük yoktur: bir saldırgan, verileri XORing yaparak şifreleme metnini değiştirebilir ve verilerin içeriğini değiştirebilir.

Götürün: Şifreleme metnindeki değişiklikler algılanmaz ve düz metin üzerinde öngörülebilir bir etkiye sahiptir.

Çözüm

İleti bütünlüğü denetimleri içeren bu durumlar için bir Blok şifreleme kullanın

1

Standartlara Güvenmeyin.

Şifrelemede birçok standart vardır ve bazen bunları kullanmanız gerekir. Ancak standartları yazan insanların ihtiyaç duydukları şifrelemeyi yeterince anladıklarını varsaymayın. Örneğin, EAX bir ağ standardında elden geçirildi. EAX'in bir güvenlik kanıtı vardır. Yenilenen versiyon olmadı.

MD5 bir standarttır. Şimdi kırıldı. Chip ve PIN birçok tehlikeli özellik sayesinde defalarca kırıldı. GPG, konfor için çok kısa olan DSA anahtarlarını destekliyor. SSL kullanılmaması gereken seçenekler ve gerektiriyor onlardan kaçınmaya özen gösterin.

Bu konuda ne yapılabilir? Dikkatli olmak, bilinen riskleri anlamak ve araştırmaya yenilerini katmak.

1
Watson Ladd

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

MAC, belirli bir düz metnin mesaj bütünlüğünü (değişiklik yok, vb.) Sağlayan bir karma koddur. Birçok uygulama ve yayınlanan standart, bir MAC'i MAC'a ek veri ekleyen bir saldırgandan koruyamaz.

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

ECBC ve NMAC, mesaj uzantısı saldırısını doğru bir şekilde önleyen şifrelerin örnekleridir.

Çözüm:

  • raw CBC Yerine Encrypted CBC (ECBC) kullanın
  • NMAC yerine cascade kullanın
0

Asla Tek Seferlik Pad (OTP) veya akış şifre anahtarını bir kereden fazla kullanmayın

İki kez uygulanan bir OTP, "mükemmel gizlilik" ile şifrelenen verilerin şifresinin çözüleceği ve net olacağı anlamına gelir. Bunun nedeni, verilerin iki kez XOR'lanmış olmasıdır.

Örnek

Aynı anahtarla bir OTP/veya akışın yeniden kullanıldığını varsayın.

Saldırgan, bir istemciden bir sunucuya gönderilen çok sayıda veri toplar ve XOR, iki paket birbirinin şifresini çözene (veya alt kümeye) kadar iki paket kümesini bir araya getirir.

ASCII kodlaması, yeterli şifreleme metni verildiğinde, orijinal iletilerin deşifre edilebileceği anlamına gelir (gizli OTP anahtarıyla birlikte).

Gerçek dünya örnekleri

  • Ruslar tarafından kullanılan ve daha sonra ABD istihbarat ajansı tarafından çözülen bir OTP örneği için Verona Projesi (1941-46)

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

  • WEP, 2 ^ 24 paket gönderildikten sonra veya bir NIC kart sıfırlandığında) aynı anahtarı yeniden kullanır. İlk sorun IV'ün 24 bit uzunluğunda olması ve bunun sonucunda 16 Milyon kare sonra İkinci sorun, güç döngüsünün ardından IV'ün sıfırlandığı ve iki zaman pedi ile sonuçlandığı donanım uygulamalarında meydana gelir ve IV net bir şekilde gönderildiği için bu sorunu görmek kolaydır.

Tavsiyeler

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

  • İstemci, sunucuyla birlikte bir OTP (veya PRG w/akış şifresi) kullanmalı ve sunucu, istemciye veri şifreleme yaparken farklı anahtar kullanmalıdır

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

  • Tüm PRG'lerin artış modunda çalışmak için yapılmadığını ve rasgele girdi gerekebileceğini bilin. (RC4'te bu sorun artış modunda vardır)

0

RC4 kullanmayın

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

Zayıflıklar var

  1. İlk çıktıda yanlılık var: Pr [2. bayt = 0] = 2/256
  2. Onaltı bitin sıfıra eşit olma olasılığı 1/256 ^ 2 + 1/256 ^ 3'tür. Bu, birkaç Gig veri şifrelendikten sonra gerçekleşir.
  3. Sadece IV'ün değiştiği ancak anahtarın aynı kaldığı ilgili anahtar saldırılara karşı savunmasız.

Alınız RC4 kullanmanız gerekiyorsa, ilk 256 baytı önyargılı olarak dikkate almayınız. Gigs veri grupları için RC4 kullanıyorsanız, RC4'teki önyargı, önceden şifrelenmiş tüm verilerin saldırılarına izin verir.

0

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

Her akış şifresi donanım veya yazılımda uygulanacak şekilde tasarlanmamıştır. Doğrusal geri bildirim kaydırma yazmacı (LFSR) , kolayca dağılabilen, yaygın olarak kullanılan bir donanım şifresine bir örnektir.

LFSR şunlarda 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 bir şekilde konuşlandırılmıştır ve bu nedenle güncellenmesi veya modern standartlara getirilmesi zordur. Yukarıdakilerin hepsi kötü bir şekilde kırılmıştır ve güvenli iletişim için güvenilir olmamalıdır.

Saldırı:

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

Bu neredeyse yeni değil, ancak bu sorunu gösteren FOSS'un bulunması kolaydır.

Çözüm:

eStream project (2008 yılında) 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ımda hem de yazılımda kolayca kullanılmak üzere tasarlanmıştır. Özellikle, x86 SSE2 komut setine dahildir.

Kenara

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

PRG          Speed (MB/sec)
RC4              126         (obsolete)
Salsa20/12       643         (modern)
Sosemaunk        727         (modern)
0