Мои векторы инициализации AES, похоже, ничего не делают с AESCryptoServiceProvider в C#
Я проводил некоторые исследования по использованию AESCryptoServiceProvider в C#. Пока у меня есть реализация, которая, кажется, работает. Однако я понимаю, что векторы инициализации таковы, что они должны защищать мой зашифрованный текст от одинакового, когда полезная нагрузка и ключ совпадают, но, похоже, я что-то делаю не так. Изменение моего вектора инициализации, похоже, никак не влияет на результаты этих функций.
Вот мои функции:
public string EncryptString(string toEncrypt, byte[] encryptionKey, byte[] iv)
{
var toEncryptBytes = Encoding.Default.GetBytes(toEncrypt);
using (var aes = new AesCryptoServiceProvider())
{
aes.Key = encryptionKey;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
//aes.GenerateIV();
aes.IV = iv;
using (var encryptor = aes.CreateEncryptor(encryptionKey, aes.IV))
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
using (var bWriter = new BinaryWriter(cs))
{
bWriter.Write(aes.IV, 0, aes.IV.Length);
bWriter.Write(toEncryptBytes, 0, toEncryptBytes.Length);
cs.FlushFinalBlock();
}
return Convert.ToBase64String(ms.ToArray());
}
}
}
public string DecryptString(string toDecrypt, byte[] encryptionKey, byte[] iv)
{
using (var aes = new AesCryptoServiceProvider())
{
aes.Key = encryptionKey;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
var toDecryptBytes = Convert.FromBase64String(toDecrypt);
Array.Copy(toDecryptBytes, 0, iv, 0, iv.Length);
aes.IV = iv;
using (var ms = new MemoryStream())
{
using (var cs = new CryptoStream(ms, aes.CreateDecryptor(aes.Key, iv), CryptoStreamMode.Write))
using (var binWriter = new BinaryWriter(cs))
{
binWriter.Write(toDecryptBytes, iv.Length, toDecryptBytes.Length - iv.Length);
}
return Encoding.Default.GetString(ms.ToArray());
}
}
}
Новая версия моей функции шифрования теперь у меня по совету @owlstead, меняя режим CBC обратно. Похоже, что теперь это работает правильно с использованием CBC.
public string EncryptString(string toEncrypt, byte[] encryptionKey)
{
var toEncryptBytes = Encoding.Default.GetBytes(toEncrypt);
using (var aes = new AesCryptoServiceProvider())
{
aes.Key = encryptionKey;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.GenerateIV();
using (var encryptor = aes.CreateEncryptor(encryptionKey, aes.IV))
using (var ms = new MemoryStream())
{
ms.Write(aes.IV, 0, aes.IV.Length);
using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
using (var bWriter = new BinaryWriter(cs))
{
bWriter.Write(toEncryptBytes, 0, toEncryptBytes.Length);
cs.FlushFinalBlock();
}
return Convert.ToBase64String(ms.ToArray());
}
}
}
2 ответа
Вы кладете CryptoStream
и BinaryWriter
в неправильном порядке, по крайней мере, для функции шифрования. Вы в настоящее время шифруете свой IV, в то время как IV должен быть помещен перед зашифрованным текстом, простым текстом.
IV шифруется обычным текстом перед шифрованием. Теперь это означает, что вы обнуляете простой текст: вы шифруете блок с нулевым значением.
Режим CipherMode.ECB, кажется, не принимает аргумент IV (что означает, что независимо от того, какой IV вы передали, результат будет одинаковым), это возможно, потому что ECB не нуждается в концепции в качестве начального вектора, поскольку нет последующих векторов или. Если вы хотите замаскировать свой блок ECB, XOR ваш блок вручную, прежде чем шифрование в порядке. В то время как вы изменили на CipherMode.CBC, IV имеет значение , для последующих блоков будет XOR с предыдущим зашифрованным блоком, так как образует цепочку.