it-swarm-id.com

Pelajaran yang dipelajari dan kesalahpahaman tentang enkripsi dan kriptologi

Kriptologi adalah subjek yang luas sehingga pembuat kode yang berpengalaman pun hampir selalu akan membuat kesalahan beberapa kali pertama. Namun enkripsi adalah topik yang sangat penting, seringkali kita tidak mampu melakukan kesalahan ini.

Maksud dari pertanyaan ini adalah untuk mengidentifikasi dan mendaftar apa yang tidak harus dilakukan dengan algoritma atau API yang diberikan. Dengan cara ini kita bisa belajar dari pengalaman orang lain dan mencegah penyebaran praktik buruk.

Untuk menjaga agar pertanyaan ini konstruktif, silakan

  1. Sertakan contoh "salah"
  2. Jelaskan apa yang salah dengan contoh itu
  3. Berikan implementasi yang benar (jika ada).
  4. Untuk yang terbaik dari kemampuan Anda, berikan referensi mengenai # 2 dan # 3 di atas.
68

Jangan gulung crypto Anda sendiri.

Jangan ciptakan algoritma atau protokol enkripsi Anda sendiri; itu sangat rawan kesalahan. Seperti yang dikatakan Bruce Schneier,

"Siapa pun dapat menemukan algoritme enkripsi yang tidak dapat mereka hancurkan; jauh lebih sulit untuk menemukan yang tidak dapat dipecahkan orang lain".

Algoritma Crypto sangat rumit dan perlu pemeriksaan intensif untuk memastikan mereka aman; jika Anda menciptakan milik Anda sendiri, Anda tidak akan mendapatkannya, dan sangat mudah untuk berakhir dengan sesuatu yang tidak aman tanpa disadari.

Sebagai gantinya, gunakan algoritma dan protokol kriptografi standar. Kemungkinannya adalah orang lain pernah mengalami masalah Anda sebelumnya dan merancang algoritma yang sesuai untuk tujuan itu.

Kasus terbaik Anda adalah menggunakan skema tingkat tinggi yang diperiksa dengan baik: untuk keamanan komunikasi, gunakan TLS (atau SSL); untuk data saat istirahat, gunakan GPG (atau PGP). Jika Anda tidak dapat melakukannya, gunakan pustaka crypto tingkat tinggi, seperti cryptlib , GPGME, Keyczar , atau NaCL , alih-alih sebuah tingkat rendah, seperti OpenSSL, CryptoAPI, JCE, dll. Terima kasih kepada Nate Lawson untuk saran ini.

76
D.W.

Jangan gunakan enkripsi tanpa otentikasi pesan

Ini adalah kesalahan yang sangat umum untuk mengenkripsi data tanpa juga mengesahkannya.

Contoh: Pengembang ingin merahasiakan pesan, sehingga mengenkripsi pesan dengan mode AES-CBC. Kesalahan: Ini tidak cukup untuk keamanan di hadapan serangan aktif, serangan replay, serangan reaksi, dll. Ada serangan yang dikenal pada enkripsi tanpa otentikasi pesan, dan serangan bisa sangat serius. Cara mengatasinya adalah dengan menambahkan otentikasi pesan.

Kesalahan ini telah menyebabkan kerentanan serius dalam sistem yang digunakan yang menggunakan enkripsi tanpa otentikasi, termasuk ASP.NET , XML enkripsi , Amazon EC2 , JavaServer Faces, Ruby pada Rails, OWASP ESAPI , IPSEC , WEP , ASP.NET lagi , dan SSH2 Anda tidak ingin menjadi yang berikutnya dalam daftar ini.

Untuk menghindari masalah ini, Anda perlu menggunakan otentikasi pesan setiap kali Anda menerapkan enkripsi. Anda memiliki dua pilihan cara melakukannya:

  • Mungkin solusi paling sederhana adalah dengan menggunakan skema enkripsi yang menyediakan enkripsi terotentikasi , mis., GCM, CWC, EAX, CCM, OCB. (Lihat juga: 1 .) Skema enkripsi terotentikasi menangani ini untuk Anda, sehingga Anda tidak perlu memikirkannya.

  • Atau, Anda dapat menerapkan otentikasi pesan Anda sendiri, sebagai berikut. Pertama, mengenkripsi pesan menggunakan skema enkripsi kunci-simetris yang sesuai (mis., AES-CBC). Kemudian, ambil seluruh ciphertext (termasuk infus, nonces, atau nilai lain yang diperlukan untuk dekripsi), terapkan kode otentikasi pesan (misalnya, AES-CMAC, SHA1-HMAC, SHA256-HMAC), dan tambahkan hasil intisari MAC yang dihasilkan ke ciphertext sebelum pengiriman. Di sisi penerima, periksa bahwa intisari MAC valid sebelum mendekripsi. Ini dikenal sebagai konstruksi terenkripsi-kemudian-otentikasi. (Lihat juga: 1 , 2 .) Ini juga berfungsi dengan baik, tetapi membutuhkan sedikit lebih banyak perhatian dari Anda.

47
D.W.

Hati-hati saat menyatukan beberapa string, sebelum hashing.

Kadang saya melihat kesalahan: Orang menginginkan hash dari string S dan T. Mereka menggabungkan mereka untuk mendapatkan string tunggal S || T, kemudian hash untuk mendapatkan H (S || T). Ini cacat.

Masalahnya: Rangkaian meninggalkan batas antara dua string yang ambigu. Contoh: builtin || securely = built || insecurely. Dengan kata lain, hash H (S || T) tidak secara unik mengidentifikasi string S dan T. Oleh karena itu, penyerang mungkin dapat mengubah batas antara dua string, tanpa mengubah hash. Misalnya, jika Alice ingin mengirim dua string builtin dan securely, penyerang dapat mengubahnya menjadi dua string built dan insecurely tanpa membatalkan hash.

Masalah serupa berlaku ketika menerapkan tanda tangan digital atau kode otentikasi pesan ke rangkaian string.

Cara mengatasinya: daripada penggabungan sederhana, gunakan beberapa pengkodean yang jelas diterjemahkan. Misalnya, alih-alih menghitung H (S || T), Anda bisa menghitung H (panjang (S) || S || T), di mana panjang (S) adalah nilai 32-bit yang menunjukkan panjang S dalam byte. Atau, kemungkinan lain adalah menggunakan H (H (S) || H (T)), atau bahkan H (H (S) || T).

Untuk contoh dunia nyata dari cacat ini, lihat cacat ini di Amazon Web Services atau cacat ini di Flickr [pdf].

36
D.W.

Jangan menggunakan kembali nonces atau infus

Banyak mode operasi memerlukan IV (Initialization Vector). Anda tidak boleh menggunakan kembali nilai yang sama untuk IV dua kali; hal tersebut dapat membatalkan semua jaminan keamanan dan menyebabkan pelanggaran keamanan yang sangat besar.

  • Untuk mode operasi stream cipher, seperti mode CTR atau mode OFB, menggunakan kembali IV adalah bencana keamanan. Ini dapat menyebabkan pesan terenkripsi dapat dipulihkan secara sepele.

  • Untuk mode operasi lainnya, seperti mode CBC, menggunakan kembali IV juga dapat memfasilitasi serangan pemulihan plaintext dalam beberapa kasus.

Apa pun mode operasi yang Anda gunakan, Anda tidak harus menggunakan kembali IV. Jika Anda bertanya-tanya bagaimana cara melakukannya dengan benar, spesifikasi NIST memberikan dokumentasi terperinci tentang cara menggunakan mode operasi cipher blok dengan benar.

Proyek Tarsnap memberikan contoh yang baik dari perangkap ini. Tarsnap mengenkripsi data cadangan dengan membaginya menjadi potongan-potongan dan kemudian mengenkripsi setiap potongan dengan AES dalam mode CTR. Dalam versi 1.0.22 hingga 1.0.27 dari Tarsnap, IV yang sama secara tidak sengaja digunakan kembali, memungkinkan pemulihan plaintext.

Bagaimana ini bisa terjadi? Untuk menyederhanakan kode Tarsnap - dan dengan harapan mengurangi potensi bug - Colin Percival mengambil kesempatan untuk "refactor" kode AES-CTR ke file baru (lib/crypto/crypto_aesctr.c dalam kode sumber Tarsnap ) dan memodifikasi tempat yang ada di mana AES-CTR digunakan untuk mengambil keuntungan dari rutinitas ini. Kode baru terlihat seperti ini:

/* Enkripsi data. */
 - aes_ctr (& encr_aes-> key, encr_aes-> nonce ++, buf, len, 
 - filebuf + CRYPTO_FILE_HLEN); 
 + if ((stream = 
 + crypto_aesctr_init (& encr_aes-> key, encr_aes-> nonce)) == NULL) 
 + goto err0; 
 + crypto_aesctr_stream (stream, buf, filebuf + CRYPTO_FILE_HLEN, len;) .] + crypto_aesctr_free (stream); 

Selama refactoring, encr_aes->nonce++ secara tidak sengaja berubah menjadi encr_aes->nonce, dan sebagai hasilnya nilai nonce yang sama digunakan berulang kali . Secara khusus, nilai CTR nonce tidak bertambah setelah setiap chunk dienkripsi. (Penghitung CTR secara benar bertambah setelah setiap 16 byte data diproses, tetapi penghitung ini disetel ulang ke nol untuk setiap potongan yang baru.) Detail lengkap dijelaskan oleh Colin Percival di: http: //www.daemonology. net/blog/2011-01-18-tarsnap-critical-security-bug.html

29
Alex Holst

Pastikan Anda menabur generator angka acak dengan entropi yang cukup.

Pastikan Anda menggunakan generator nomor acak crypto-strength untuk hal-hal seperti menghasilkan kunci, memilih IVs/nonces, dll. Jangan gunakan Rand(), random(), drand48() , dll.

Pastikan Anda menyemai generator nomor pseudorandom dengan cukup entropi. Jangan menaburinya dengan waktu sehari; itu bisa ditebak.

Contoh: srand(time(NULL)) sangat buruk. Cara yang baik untuk menaburkan PRNG adalah dengan mengambil 128 bit atau angka benar-benar acak, mis., Dari /dev/urandom, CryptGenRandom, atau serupa. Di Jawa, gunakan SecureRandom, bukan Acak. Di .NET, gunakan System.Security.Cryptography.RandomNumberGenerator, bukan System.Random. Dalam Python, gunakan random. SystemRandom, bukan acak. Terima kasih kepada Nate Lawson untuk beberapa contoh.

Contoh dunia nyata: lihat cacat pada versi awal browser Netscape , yang memungkinkan penyerang merusak SSL.

29
D.W.

Jangan gunakan cipher blok dengan ECB untuk enkripsi simetris

(Berlaku untuk AES, 3DES, ...)

Berikut adalah post dan sangat mirip artikel Microsoft KB tentang bagaimana mode ECB menghasilkan kode yang tidak dienkripsi.

Juga lihat pos serupa ini from Rook

Pesan teks biasa:

alt text

Pesan yang sama dienkripsi dengan mode ECB (tidak peduli cipher apa yang Anda gunakan): alt text

Pesan yang sama persis menggunakan mode CBC (sekali lagi, tidak masalah cipher apa yang Anda gunakan): alt text

Cara yang salah

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);
}

Kesalahan ada di baris berikut

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


Cara yang benar

Orang-orang baik di Microsoft mengirimi saya kode berikut untuk memperbaiki artikel KB yang ditautkan di atas. Ini dirujuk dalam kasus # 111021973179005

Kode sampel ini menggunakan AES untuk mengenkripsi data, dan kunci untuk enkripsi AES adalah kode hash yang dihasilkan oleh SHA256. AES adalah algoritma Advanced Encryption Standard (AES). Algoritma AES didasarkan pada permutasi dan pergantian. Permutasi adalah pengaturan ulang data, dan penggantian menggantikan satu unit data dengan yang lainnya. AES melakukan permutasi dan pergantian menggunakan beberapa teknik yang berbeda. Untuk detail lebih lanjut tentang AES, silakan merujuk ke artikel "Jaga Data Anda Aman dengan Standar Enkripsi Lanjutan Baru" di Majalah MSDN di http://msdn.Microsoft.com/en-us/magazine/cc164055.aspx .

SHA adalah Algoritma Secure Hash. SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512) sekarang direkomendasikan. Untuk informasi lebih lanjut tentang Nilai Hash di .NET Framework, silakan merujuk ke http://msdn.Microsoft.com/en-us/library/92f9ye3s.aspx#hash_values .

Nilai default mode untuk operasi algoritma simetrik untuk AesCryptoServiceProvider adalah CBC. CBC adalah mode Chaining Block Chaining. Ini memperkenalkan umpan balik. Sebelum setiap blok teks biasa dienkripsi, ia digabungkan dengan teks sandi blok sebelumnya dengan operasi bitwise eksklusif OR. Ini memastikan bahwa bahkan jika teks biasa berisi banyak blok identik, mereka akan masing-masing mengenkripsi ke blok teks sandi yang berbeda. Vektor inisialisasi digabungkan dengan blok teks biasa pertama dengan operasi bitwise eksklusif OR sebelum blok dienkripsi. Jika sedikit pun dari blok teks sandi tersebut hancur, blok teks biasa yang sesuai juga akan hancur. Selain itu, sedikit di blok berikutnya, di posisi yang sama dengan bit yang rusak, akan hancur. Untuk informasi lebih detail tentang CipherMode, silakan lihat http://msdn.Microsoft.com/en-us/library/system.security.cryptography.ciphermode.aspx .

Ini kode contohnya.

// 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));
}

Untuk detail lebih lanjut dari kelas-kelas dalam kode sampel, silakan merujuk ke tautan berikut:

· Kelas AesCryptoServiceProvider

· SHA256Managed Class

· CryptoStream Class

Selain itu, ada beberapa artikel yang dapat membantu mendapatkan pemahaman yang lebih baik tentang kriptografi di .NET Framework, silakan merujuk ke tautan di bawah ini:

· Layanan Kriptografi

· . Model Kerangka Kriptografi NET

· Panduan Sederhana untuk Kriptografi

· Enkripsi Tanpa Rahasia

20

Jangan gunakan kunci yang sama untuk enkripsi dan otentikasi. Jangan gunakan kunci yang sama untuk enkripsi dan penandatanganan.

Kunci tidak boleh digunakan kembali untuk berbagai tujuan; yang dapat membuka berbagai serangan halus.

Misalnya, jika Anda memiliki pasangan kunci publik/publik RSA, Anda sebaiknya tidak menggunakannya untuk enkripsi (mengenkripsi dengan kunci publik, mendekripsi dengan kunci pribadi) dan untuk menandatangani (menandatangani dengan kunci pribadi, verifikasi dengan kunci publik ): pilih satu tujuan dan gunakan hanya untuk satu tujuan itu. Jika Anda membutuhkan kedua kemampuan, buat dua keypairs, satu untuk masuk dan satu untuk enkripsi/dekripsi.

Demikian pula, dengan kriptografi simetris, Anda harus menggunakan satu kunci untuk enkripsi dan kunci independen terpisah untuk otentikasi pesan. Jangan gunakan kembali kunci yang sama untuk kedua tujuan.

20
D.W.

Prinsip Kerckhoffs: Sebuah cryptosystem harus aman bahkan jika segala sesuatu tentang sistem, kecuali kuncinya, adalah pengetahuan umum

Contoh yang salah: hash LANMAN

Hash LANMAN akan sulit diketahui jika tidak ada yang tahu algoritma, namun begitu algoritma diketahui sekarang sangat sepele untuk dipecahkan.

Algoritma adalah sebagai berikut ( dari wikipedia ):

  1. Pengguna ASCII kata sandi dikonversi menjadi huruf besar.
  2. Kata sandi ini diisi dengan nol hingga 14 byte
  3. Kata sandi "fixed-length" dibagi menjadi dua bagian tujuh byte.
  4. Nilai-nilai ini digunakan untuk membuat dua DES kunci, satu dari masing-masing setengah 7-byte
  5. Masing-masing dari dua kunci digunakan untuk DES-mengenkripsi konstanta ASCII string “KGS! @ # $%”, Menghasilkan dua nilai ciphertext 8-byte.
  6. Kedua nilai ciphertext ini digabungkan untuk membentuk nilai 16-byte, yang merupakan hash LM

Karena Anda sekarang tahu ciphertext dari fakta-fakta ini, Anda sekarang dapat dengan mudah memecah ciphertext menjadi dua ciphertext yang Anda tahu adalah huruf besar yang mengakibatkan serangkaian karakter kata sandi yang terbatas.

Contoh yang benar: Enkripsi AES

  • Algoritma yang dikenal
  • Timbangan dengan teknologi. Meningkatkan ukuran kunci saat membutuhkan semangat kriptografis yang lebih banyak
17
Chris Dale

Cobalah untuk menghindari menggunakan kata sandi sebagai kunci enkripsi.

Kelemahan umum dalam banyak sistem adalah menggunakan kata sandi atau frasa sandi, atau kata sandi atau frasa sandi, sebagai kunci enkripsi/dekripsi. Masalahnya adalah bahwa ini cenderung sangat rentan terhadap serangan pencarian kunci offline. Sebagian besar pengguna memilih kata sandi yang tidak memiliki cukup entropi untuk menahan serangan tersebut.

Perbaikan terbaik adalah dengan menggunakan kunci enkripsi/dekripsi yang benar-benar acak, bukan yang secara deterministik dihasilkan dari kata sandi/kata sandi.

Namun, jika Anda harus menggunakannya berdasarkan kata sandi/frasa sandi, gunakan skema yang sesuai untuk memperlambat pencarian kunci lengkap. Saya sarankan PBKDF2 , yang menggunakan haser berulang (sepanjang baris H(H(H(....H(password)...)))) untuk memperlambat pencarian kamus. Aturlah untuk menggunakan cukup banyak iterasi untuk membuat proses ini mengambil, katakanlah, 100 ms pada mesin pengguna untuk menghasilkan kunci.

13
D.W.

Dalam protokol kriptografi: Jadikan setiap pesan teridentifikasi dapat dikenali: tidak ada dua pesan yang terlihat sama

Generalisasi/varian dari:

  • Hati-hati saat menggabungkan beberapa string, sebelum hashing.
  • Jangan menggunakan kembali kunci.
  • Jangan menggunakan kembali nonces.

Selama menjalankan protokol kriptografi, banyak pesan yang tidak dapat dipalsukan tanpa rahasia (kunci atau nonce) dapat dipertukarkan. Pesan-pesan ini dapat diverifikasi oleh yang diterima karena dia tahu kunci publik (tanda tangan), atau karena hanya dia dan pengirim yang tahu kunci simetris, atau nonce. Ini memastikan bahwa pesan-pesan ini belum dimodifikasi.

Tapi ini tidak tidak memastikan bahwa pesan-pesan ini telah dipancarkan selama menjalankan protokol yang sama: musuh mungkin telah menangkap pesan-pesan ini sebelumnya, atau selama menjalankan protokol secara bersamaan. Musuh dapat memulai banyak menjalankan protokol kriptografi secara bersamaan untuk menangkap pesan yang valid dan menggunakannya kembali tanpa dimodifikasi.

Dengan memutar ulang pesan secara cerdik, dimungkinkan untuk menyerang protokol tanpa mengorbankan kunci primer apa pun, tanpa menyerang RNG, cypher, dll.

Dengan membuat setiap pesan yang diautentikasi dari protokol jelas berbeda untuk penerima, peluang untuk memutar ulang pesan yang tidak dimodifikasi berkurang (tidak dihilangkan).

13
curiousguy

Jangan gunakan panjang kunci tidak aman.

Pastikan Anda menggunakan algoritma dengan kunci yang cukup panjang.

Untuk kriptografi kunci-simetris, saya akan merekomendasikan setidaknya kunci 80-bit, dan jika mungkin, kunci 128-bit adalah ide yang bagus. Jangan gunakan crypto 40-bit; itu tidak aman dan mudah rusak oleh amatir, hanya dengan mencoba semua kunci yang ada secara menyeluruh. Jangan gunakan DES 56-bit; itu tidak sepele untuk istirahat, tetapi itu berada dalam jangkauan penyerang yang berdedikasi untuk memecahkan DES. Algoritma 128-bit, seperti AES, tidak jauh lebih lambat dari crypto 40-bit, jadi Anda tidak punya alasan untuk menggunakan crypto yang payah.

Untuk kriptografi kunci publik, rekomendasi panjang kunci tergantung pada algoritma dan tingkat keamanan yang diperlukan. Juga, meningkatkan ukuran kunci tidak merusak kinerja, sehingga pembunuhan massal yang berlebihan tidak ekonomis; dengan demikian, ini membutuhkan sedikit lebih banyak pemikiran daripada pemilihan ukuran kunci symmetric-key. Untuk RSA, El Gamal, atau Diffie-Hellman, saya merekomendasikan bahwa kuncinya setidaknya 1024 bit, sebagai minimum absolut; Namun, kunci 1024-bit berada di Tepi dari apa yang mungkin menjadi mudah retak dalam waktu dekat dan umumnya tidak direkomendasikan untuk penggunaan modern, jadi jika mungkin, saya akan merekomendasikan 1536 - atau bahkan 2048-bit kunci. Untuk kriptografi kurva elips, tombol 160-bit tampak memadai, dan kunci 224-bit lebih baik. Anda juga dapat merujuk pada pedoman pedoman yang diterbitkan kesetaraan kasar antara ukuran kunci simetris dan kunci publik .

8
D.W.

Jangan gunakan kunci yang sama di kedua arah.

Dalam komunikasi jaringan, kesalahan umum adalah menggunakan kunci yang sama untuk komunikasi dalam arah A-> B seperti untuk arah B-> A. Ini adalah ide yang buruk, karena sering memungkinkan serangan replay yang memutar ulang sesuatu yang dikirim ke B, kembali ke A.

Pendekatan teraman adalah menegosiasikan dua kunci independen, satu untuk setiap arah. Atau, Anda dapat menegosiasikan satu kunci K, kemudian gunakan K1 = AES (K, 00..0) untuk satu arah dan K2 = AES (K, 11..1) untuk arah lainnya.

8
D.W.

Pad sekali pakai bukan pad sekali pakai jika kunci diregangkan oleh suatu algoritma

Pengidentifikasi "bantalan sekali pakai" (juga dikenal sebagai sandi Vernam) sering kali salah diterapkan ke berbagai solusi kriptografi dalam upaya untuk mengklaim keamanan yang tidak dapat dipecahkan. Namun menurut definisi, sandi Vernam aman jika dan hanya jika ketiga kondisi ini terpenuhi:

  • Materi kuncinya benar-benar tidak dapat diprediksi; DAN
  • Bahan kuncinya sama panjangnya dengan plaintext; DAN
  • Bahan kuncinya tidak pernah digunakan kembali.

Setiap pelanggaran terhadap kondisi tersebut berarti itu bukan lagi cipher pad satu kali.

Kesalahan umum yang dibuat adalah bahwa kunci pendek diregangkan dengan suatu algoritma. Tindakan ini melanggar aturan tak terduga (apalagi aturan panjang kunci). Setelah ini dilakukan, pad sekali pakai secara matematis ditransformasikan menjadi algoritma peregangan kunci. Menggabungkan kunci pendek dengan byte acak hanya mengubah ruang pencarian yang diperlukan untuk memaksa algoritma peregangan kunci. Demikian pula, menggunakan byte "yang dihasilkan secara acak" mengubah algoritma penghasil angka acak menjadi algoritma keamanan.

Ini adalah contoh sederhana. Saya punya pesan bahwa saya akan mengenkripsi menggunakan "pad sekali pakai" yang menggunakan fungsi aman secara kriptografis sebagai generator kunci. Saya memilih kunci rahasia, lalu menambahkan nomor acak untuk memastikannya tidak akan digunakan kembali. Karena saya tidak menggunakan kembali kunci, tidak ada cara untuk menyerang ciphertext dengan mengurangi satu pesan dari yang lain.

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

Materi kuncinya dibuat dengan aman menggunakan SHA-1 untuk mem-hash kata sandi rahasia saya (ditambah acak) untuk merentangkannya. Tetapi setiap penyerang yang mengetahui algoritma peregangan * yang digunakan adalah SHA-1 dapat menyerangnya dengan mencoba berbagai input ke SHA-1 dan XORing output dengan ciphertext. Menebak tombol "OTP" sekarang tidak lebih sulit daripada menebak input gabungan untuk algoritma kriptografi. Properti ini berlaku terlepas dari algoritma kriptografi dasar mana yang dipilih, ukuran kompleksitas apa yang dipegangnya, atau bagaimana penerapannya atau diunggulkan.

Anda mungkin memiliki algoritma peregangan kunci yang sangat baik. Anda juga dapat memiliki generator nomor acak yang sangat aman. Namun, algoritme Anda secara definisi bukan pad sekali pakai, dan karenanya tidak memiliki properti yang tidak bisa dilanggar dari pad sekali pakai.

* Menerapkan prinsip Kerckhoff berarti Anda harus menganggap penyerang selalu dapat menentukan algoritma yang digunakan.

3
John Deters

Gunakan mode yang benar

Setara, jangan mengandalkan pengaturan default perpustakaan untuk aman. Secara khusus, banyak perpustakaan yang menerapkan AES mengimplementasikan algoritma yang dijelaskan dalam FIPS 197, yang disebut mode ECB (Buku Kode Elektronik), yang pada dasarnya adalah pemetaan langsung dari:

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

sangat tidak aman. Alasannya sederhana, sementara jumlah kunci yang mungkin di ruang kunci cukup besar, tautan lemah di sini adalah jumlah entropi dalam pesan. Seperti biasa, xkcd.com menjelaskan lebih baik daripada saya http://xkcd.com/257/

Sangat penting untuk menggunakan sesuatu seperti CBC (Cipher Block Chaining) yang pada dasarnya membuat ciphertext [i] pemetaan:

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

Hanya untuk menunjukkan beberapa perpustakaan bahasa di mana kesalahan semacam ini mudah dilakukan: http://golang.org/pkg/crypto/aes/ menyediakan implementasi AES yang, jika digunakan secara naif, akan menghasilkan mode ECB.

Perpustakaan pycrypto default ke mode ECB saat membuat objek AES baru.

OpenSSL, lakukan ini dengan benar. Setiap panggilan AES secara eksplisit tentang mode operasi. Sungguh hal yang paling aman IMO adalah hanya mencoba untuk tidak melakukan crypto tingkat rendah seperti ini sendiri. Jika Anda terpaksa, lanjutkan seolah-olah Anda berjalan di atas pecahan kaca (dengan hati-hati), dan cobalah untuk memastikan pengguna Anda dibenarkan untuk menaruh kepercayaan mereka pada Anda untuk melindungi data mereka.

3
Shane Hansen

Jangan menggunakan kembali kunci yang sama pada banyak perangkat.

Semakin banyak Anda berbagi kunci kriptografi, semakin kecil kemungkinan Anda akan dapat menyimpannya. Beberapa sistem yang digunakan telah menggunakan kembali kunci simetris yang sama ke setiap perangkat pada sistem. Masalahnya adalah cepat atau lambat, seseorang akan mengekstrak kunci dari satu perangkat, dan kemudian mereka akan dapat menyerang semua perangkat lainnya. Jadi, jangan lakukan itu.

Lihat juga "Enkripsi Simetris Jangan # 6: Jangan membagikan kunci tunggal di banyak perangkat" di artikel blog ini . Penghargaan untuk Matthew Green.

3
D.W.

Jangan gunakan OTP atau stream cipher dalam enkripsi disk

Contoh 1

Misalkan dua file disimpan menggunakan stream cipher/OTP. Jika file disimpan ulang setelah edit kecil, penyerang dapat melihat bahwa hanya bit tertentu yang diubah dan menyimpulkan informasi tentang dokumen. (Bayangkan mengubah salam "Bob Terkasih" menjadi "Dear Alice").

Contoh 2

Tidak ada integritas dalam output: penyerang dapat memodifikasi ciphertext dan memodifikasi isi data hanya dengan XORing data.

Ambil: Modifikasi ke ciphertext tidak terdeteksi dan memiliki dampak yang dapat diprediksi pada plaintext.

Solusi

Gunakan Block cipher untuk situasi ini yang mencakup pemeriksaan integritas pesan

1

Jangan Percayai Standar.

Banyak standar ada dalam kriptografi, dan kadang-kadang Anda harus menggunakannya. Tetapi jangan berasumsi bahwa orang yang menulis standar memahami kriptografi yang mereka butuhkan. Misalnya, EAX dikerjakan ulang dalam standar jaringan. EAX memiliki bukti keamanan. Versi ulang tidak.

MD5 adalah standar. Sekarang rusak. Chip dan PIN telah berkali-kali rusak, berkat banyak fitur berbahaya. GPG masih mendukung kunci DSA yang terlalu pendek untuk kenyamanan. SSL memiliki opsi yang tidak boleh digunakan, dan membutuhkan peduli untuk menghindarinya.

Apa yang bisa dilakukan tentang ini? Berhati-hati, memahami risiko yang diketahui, dan mengikuti penelitian ke risiko baru.

1
Watson Ladd

Hanya gunakan MAC yang tidak rentan terhadap serangan ekstensi pesan

MAC adalah kode hash yang memastikan integritas pesan (tidak ada modifikasi, dll) dari teks biasa yang diberikan. Banyak implementasi dan standar yang diterbitkan gagal melindungi MAC dari penyerang yang menambahkan data tambahan ke MAC.

Solusi untuk ini adalah untuk implementasi MAC menggunakan kunci kedua (berbeda) dan mengenkripsi ulang hasil akhir.

ECBC dan NMAC adalah contoh cipher yang benar mencegah serangan ekstensi pesan.

Larutan:

  • Gunakan Encrypted CBC (ECBC) alih-alih raw CBC
  • Gunakan NMAC alih-alih cascade
0

Jangan pernah menggunakan One Time Pad (OTP) atau stream cipher key lebih dari sekali

OTP yang diterapkan dua kali berarti data yang dienkripsi dengan "kerahasiaan sempurna" akan didekripsi dan di hapus. Ini terjadi karena data XOR'ed dua kali.

Contoh

Asumsikan OTP/atau streaming dengan kunci yang sama sedang digunakan kembali.

Penyerang mengumpulkan banyak data yang dikirim dari klien ke server, dan XOR satu set dua paket bersama sampai dua paket saling mendekripsi (atau subset di dalamnya).

Pengkodean ASCII memiliki redundansi yang cukup yang berarti bahwa dengan diberikan ciphertext yang cukup, pesan asli dapat diterjemahkan (bersama dengan kunci OTP rahasia).

contoh dunia nyata

  • Proyek Verona (1941-46) untuk contoh OTP yang digunakan oleh Rusia dan kemudian didekripsi oleh badan intelijen AS

  • Microsoft PPTPv1, klien dan server mengenkripsi data menggunakan kunci yang sama.

  • WEP menggunakan kembali kunci yang sama setelah 2 ^ 24 paket dikirim, atau jika kartu NIC diatur ulang. Masalah pertama adalah karena IV panjangnya 24 bit, yang menghasilkan setelah 16 juta frame adalah mentransmisikan pad dua waktu dibuat. Masalah kedua terjadi pada implementasi perangkat keras di mana setelah siklus daya, IV me-reset ke nol, menghasilkan pad dua kali. Masalah ini mudah dilihat karena IV dikirim dalam clear.

Rekomendasi

  • Kunci baru harus dibuat untuk setiap sesi (mis. TLS).

  • Klien harus menggunakan satu OTP (atau stream cipher w/PRG) dengan server, dan server harus menggunakan kunci berbeda saat mengenkripsi data ke klien

  • Daripada menghasilkan banyak banyak kunci, Anda dapat memperluas satu kunci ke aliran panjang menggunakan PRG (dengan asumsi Anda mempercayai PRG) dan menggunakan setiap segmen dari ekspansi itu sebagai kunci.

  • Ketahuilah bahwa tidak semua PRG dibuat untuk bekerja dalam mode kenaikan, dan input acak mungkin diperlukan. (RC4 memiliki masalah ini dalam mode kenaikan)

0

Jangan gunakan RC4

RC4 dirancang pada tahun 1987 untuk digunakan sebagai stream cipher. Ini digunakan dalam HTTPS dan WEP.

Ada kelemahannya

  1. Ada bias dalam output awal: Pr [byte kedua = 0] = 2/256
  2. Probabilitas enam belas bit sama dengan nol adalah 1/256 ^ 2 + 1/256 ^ 3. Ini terjadi setelah beberapa Gigs data dienkripsi.
  3. Rentan terhadap serangan kunci terkait, di mana hanya IV yang berubah tetapi kuncinya tetap sama.

Singkirkan Jika Anda harus menggunakan RC4, abaikan 256 byte pertama karena bias. Jika Anda menggunakan RC4 untuk Gigs data, maka bias di RC4 akan memungkinkan serangan semua data terenkripsi sebelumnya.

0

Gunakan prosesor aliran modern yang bekerja dengan tepat di Perangkat Keras atau Perangkat Lunak

Tidak semua stream cipher dirancang untuk diimplementasikan dalam perangkat keras atau perangkat lunak. Linear feedback shift register (LFSR) adalah contoh dari cipher perangkat keras yang digunakan secara luas yang mudah rusak.

LFSR digunakan di:

  • Enkripsi DVD (juga dikenal sebagai CSS) 2 LFSR
  • Enkripsi GSM (A5/1.2) 3 LSFR
  • Bluetooth (E0): 4 LFSR

Perangkat keras untuk di atas digunakan secara luas dan karenanya sulit untuk diperbarui, atau membawa ke standar modern. Semua hal di atas rusak parah dan tidak boleh dipercaya untuk komunikasi yang aman.

Serang:

Karena kunci dipecah menjadi dua bagian selama enkripsi (17 bit, dan 25 bit) dan bit tersebut digunakan untuk mengenkripsi teks sandi yang sama, dimungkinkan untuk menggunakan pengetahuan tentang format MPEG, dan bruteforce kunci 17bit untuk memperkirakan apa kunci 25bit adalah.

Ini bukan hal yang baru, tetapi FOSS mudah ditemukan yang menunjukkan masalah ini.

Solusi:

proyek eStream (pada 2008) memenuhi syarat 5 stream cipher yang harus digunakan. Perbedaan yang mencolok adalah bahwa alih-alih menggunakan Kunci dengan IV, sandi menggunakan Kunci, nonce, dan penghitung. Salsa20 beroperasi dengan cara ini dan dirancang untuk digunakan dengan perangkat keras dan lunak dengan mudah. Secara khusus, ini termasuk dalam set instruksi x86 SSE2.

Selain

Cipher modern tidak hanya lebih aman, tetapi mereka juga lebih cepat:

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