Подтвердить что ты не робот

Симметричное шифрование (AES): Является ли сохранение IV и Соли рядом с зашифрованными данными безопасными и правильными?

Я пытаюсь понять, как обрабатывать и управлять вектором инициализации и солью (когда это применимо) при шифровании и расшифровке данных с использованием симметричного алгоритма шифрования, в данном случае AES.

Я вывел из разных потоков SO и других других веб-сайтов, что ни IV, ни соль не должны быть секретными, уникальными только для защиты от криптоаналитических атак, таких как атака грубой силы. Имея это в виду, я понял, что было бы целесообразно хранить мой псевдослучайный IV с зашифрованными данными. Я спрашиваю, подходит ли метод, который я использую, и, кроме того, должен ли я обрабатывать мою твердую кодовую соль таким же образом? Это записывая его в поток памяти вдоль стороны IV

Мой код:

private const ushort ITERATIONS = 300;
private static readonly byte[] SALT = new byte[] { 0x26, 0xdc, 0xff, 0x00, 0xad, 0xed, 0x7a, 0xee, 0xc5, 0xfe, 0x07, 0xaf, 0x4d, 0x08, 0x22,  0x3c };

private static byte[] CreateKey(string password, int keySize)
{
    DeriveBytes derivedKey = new Rfc2898DeriveBytes(password, SALT, ITERATIONS);
    return derivedKey.GetBytes(keySize >> 3);
}

public static byte[] Encrypt(byte[] data, string password)
{
    byte[] encryptedData = null;
    using (AesCryptoServiceProvider provider = new AesCryptoServiceProvider())
    {
        provider.GenerateIV();
        provider.Key = CreateKey(password, provider.KeySize);
        provider.Mode = CipherMode.CBC;
        provider.Padding = PaddingMode.PKCS7;

        using (MemoryStream memStream = new MemoryStream(data.Length))
        {
            memStream.Write(provider.IV, 0, 16);
            using (ICryptoTransform encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write))
                {
                    cryptoStream.Write(data, 0, data.Length);
                    cryptoStream.FlushFinalBlock();
                }
            }
            encryptedData = memStream.ToArray();
        }
    }
    return encryptedData;
}

public static byte[] Decrypt(byte[] data, string password)
{
    byte[] decryptedData = new byte[data.Length];
    using (AesCryptoServiceProvider provider = new AesCryptoServiceProvider())
    {
        provider.Key = CreateKey(password, provider.KeySize);
        provider.Mode = CipherMode.CBC;
        provider.Padding = PaddingMode.PKCS7;
        using (MemoryStream memStream = new MemoryStream(data))
        {
            byte[] iv = new byte[16];
            memStream.Read(iv, 0, 16);
            using (ICryptoTransform decryptor = provider.CreateDecryptor(provider.Key, iv))
            {
                using (CryptoStream cryptoStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read))
                {
                    cryptoStream.Read(decryptedData, 0, decryptedData.Length);
                }
            }
        }
    }
    return decryptedData;
}

Я также открыт для любой другой информации о симметричном шифровании в отношении надлежащей практики.

4b9b3361

Ответ 1

Хранение IV и Соли длинное с зашифрованным текстом является правильным и наилучшим образом. Жесткое кодирование соли нецелесообразно, поскольку случайность важна, жесткое кодирование итераций совершенно нормально, но обычно намного выше 300 (фактически, по крайней мере, 1000, и вы, как правило, намного выше, если ваша машина/использование может обрабатывать ее, как в 10 секунд тысяч).

Поскольку я видел так много плохих (или старых) примеров шифрования С# из и вставлял их в открытый исходный код, я написал короткий бит кода сокращения и вставки кода Современные примеры симметричного аутентифицированного шифрования строки., которые я стараюсь обновлять и просматривать. Он хранит iv и соль с зашифрованным текстом, он также аутентифицирует зашифрованный текст и значения, включенные в текст шифрования.

В идеале, хотя лучше использовать библиотеку шифрования высокого уровня, которая будет обрабатывать лучшие методы, такие как iv для вас, однако те, которые обычно не существуют для csharp. Я работал над родным версия csharp в google keyczar. Хотя он функционально готов к использованию, я хотел больше взглянуть на код до первого официального стабильного выпуска.

Ответ 2

Да, и IV, и соль являются общественными ценностями. Что еще более важно, так это обеспечение случайных значений для каждой операции шифрования.

Чтобы привести пример этого в дикой природе, посмотрите формат данных rncryptor. Здесь соль и IV упаковываются в формат данных вместе с зашифрованным текстом и значением MAC. (Примечание: это пример objective-c).