Является ли этот код уязвимым для атаки оракула? - PullRequest
3 голосов
/ 02 мая 2019

Является ли следующий код уязвимым для атаки оракула заполнения, потому что он вернется, если заполнение допустимо или нет (CBC, PKCS # 7)?

Код взят непосредственно с веб-страницы Microsoft и может быть легко запущен на онлайн-компиляторе, таком как dotnetfiddle.net.

using System;
using System.IO;
using System.Security.Cryptography;

namespace RijndaelManaged_Example
{
    class RijndaelExample
    {
        public static void Main()
        {
            try
            {

                string original = "Here is some data to encrypt!";

                // Create a new instance of the RijndaelManaged
                // class.  This generates a new key and initialization 
                // vector (IV).
                using (RijndaelManaged myRijndael = new RijndaelManaged())
                {

                    myRijndael.GenerateKey();
                    myRijndael.GenerateIV();
                    // Encrypt the string to an array of bytes.
                    byte[] encrypted = EncryptStringToBytes(original, myRijndael.Key, myRijndael.IV);

                    // Decrypt the bytes to a string.
                    string roundtrip = DecryptStringFromBytes(encrypted, myRijndael.Key, myRijndael.IV);

                    //Display the original data and the decrypted data.
                    Console.WriteLine("Original:   {0}", original);
                    Console.WriteLine("Round Trip: {0}", roundtrip);
                }

            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.Message);
            }
        }
        static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");
            byte[] encrypted;
            // Create an RijndaelManaged object
            // with the specified key and IV.
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create an encryptor to perform the stream transform.
                ICryptoTransform encryptor = rijAlg.CreateEncryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for encryption.
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {

                            //Write all data to the stream.
                            swEncrypt.Write(plainText);
                        }
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }


            // Return the encrypted bytes from the memory stream.
            return encrypted;

        }

        static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");

            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;

            // Create an RijndaelManaged object
            // with the specified key and IV.
            using (RijndaelManaged rijAlg = new RijndaelManaged())
            {
                rijAlg.Key = Key;
                rijAlg.IV = IV;

                // Create a decryptor to perform the stream transform.
                ICryptoTransform decryptor = rijAlg.CreateDecryptor(rijAlg.Key, rijAlg.IV);

                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            // Read the decrypted bytes from the decrypting stream
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                        }
                    }
                }

            }

            return plaintext;

        }
    }
}

Программа, которую я сейчас изучаю, использует приведенный выше код для шифрования некоторых файлов XML. Вот пример файла из этой программы (файл XML только с одним элементом).

1 Ответ

3 голосов
/ 04 мая 2019

Да, код уязвим, потому что .NET по умолчанию использует CBC с PKCS # 7-совместимым заполнением по умолчанию.Вы можете легко проверить это, изменив зашифрованный текст (последние 16 байтов) и проверив, что выдается исключение.Обратите внимание, что условия ошибки не требуются для работы оракулов заполнения, различия во времени могут уже дать утечку достаточной информации.

Конечно, это не обязательно означает, что система, использующая код,уязвима.Если код используется для выполнения шифрования данных в состоянии покоя (например, шифрование файла), то вполне вероятно, что оракул заполнения не может быть создан, а необходимые условия для атаки не выполнены.

Обратите внимание, чтоатака с использованием оракула является специфическим типом атаки оракула открытым текстом.Другие атаки могут быть возможны, даже если используется другой режим блочного шифра.Как правило, вам потребуется аутентифицированное шифрование, чтобы убедиться, что открытые текстовые сообщения невозможны: действуйте только после проверки целостности и подлинности сообщения.

Показанный код не является безопасным для безопасности в транспортном режиме.Конечно, чтобы иметь безопасную транспортную безопасность, возможность оракула дополнения CBC - лишь одна из многих уязвимостей;Достаточно сказать, что фрагмент кода вообще не демонстрирует транспортную безопасность.

...