Хорошая практика вектора инициализации AES

на мой вопрос Aes Encryption ... отсутствует важная часть , теперь я узнал, что мое предположение о создании обратимого шифрования для строки было немного выключенный. Теперь у меня есть

    public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey)
    {
        var toEncryptBytes = Encoding.UTF8.GetBytes(toEncrypt);
        using (var provider = new AesCryptoServiceProvider())
        {
            provider.Key = encryptionKey;
            provider.Mode = CipherMode.CBC;
            provider.Padding = PaddingMode.PKCS7;
            using (var encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
            {
                using (var ms = new MemoryStream())
                {
                    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(toEncryptBytes, 0, toEncryptBytes.Length);
                        cs.FlushFinalBlock();
                    }
                    return ms.ToArray();
                }
            }
        }
    }

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

ОБНОВЛЕНИЕ {{ 1}} По предложению Iridium, я попробовал что-то вроде этого:

    public static byte[] EncryptString(string toEncrypt, byte[] encryptionKey)
    {
        if (string.IsNullOrEmpty(toEncrypt)) throw new ArgumentException("toEncrypt");
        if (encryptionKey == null || encryptionKey.Length == 0) throw new ArgumentException("encryptionKey");
        var toEncryptBytes = Encoding.UTF8.GetBytes(toEncrypt);
        using (var provider = new AesCryptoServiceProvider())
        {
            provider.Key = encryptionKey;
            provider.Mode = CipherMode.CBC;
            provider.Padding = PaddingMode.PKCS7;
            using (var encryptor = provider.CreateEncryptor(provider.Key, provider.IV))
            {
                using (var ms = new MemoryStream())
                {
                    ms.Write(provider.IV, 0, 16);
                    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(toEncryptBytes, 0, toEncryptBytes.Length);
                        cs.FlushFinalBlock();
                    }
                    return ms.ToArray();
                }
            }
        }
    }

    public static string DecryptString(byte[] encryptedString, byte[] encryptionKey)
    {
        using (var provider = new AesCryptoServiceProvider())
        {
            provider.Key = encryptionKey;
            provider.Mode = CipherMode.CBC;
            provider.Padding = PaddingMode.PKCS7;
            using (var ms = new MemoryStream(encryptedString))
            {
                byte[] buffer;
                ms.Read(buffer, 0, 16);
                provider.IV = buffer;
                using (var decryptor = provider.CreateDecryptor(provider.Key, provider.IV))
                {
                    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
                    {
                        byte[] decrypted = new byte[encryptedString.Length];
                        var byteCount = cs.Read(decrypted, 0, encryptedString.Length);
                        return Encoding.UTF8.GetString(decrypted, 0, byteCount);
                    }
                }
            }
        }
    }

однако это показывает что-то странное в моем модульном тесте:

    [TestMethod]
    public void EncryptionClosedLoopTest()
    {
        var roundtrip = "This is the data I am encrypting.  There are many like it but this is my encryption.";
        var encrypted = Encryption.EncryptString(roundtrip, encryptionKey);
        var decrypted = Encryption.DecryptString(encrypted, encryptionKey);
        Assert.IsTrue(roundtrip == decrypted);
    }

мой расшифрованный текст отображается как «92ʪ�F» �, hpv0�� Я шифрую . Их много, но это мое шифрование. "Которое кажется почти правильным, но, конечно, совершенно неверным. Похоже, что я близок к этому. Не хватает ли мне смещения в потоке памяти?

50
задан Community 23 May 2017 в 02:09
поделиться