我的AES初始化矢量似乎与C#中的AESCryptoServiceProvider无关
本文关键字:中的 AESCryptoServiceProvider 无关 AES 初始化 我的 | 更新日期: 2023-09-27 18:28:37
我一直在研究在C#中使用AESCryptoServiceProvider。到目前为止,我有一个似乎正在发挥作用的实现。然而,我对初始化向量的理解是,当有效载荷和密钥相同时,它应该保护我的密文不相同,但似乎我做错了什么。更改初始化向量似乎根本不会影响这些函数的结果。
以下是我的功能:
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());
}
}
}
至少对于加密函数,您将CryptoStream
和BinaryWriter
按错误的顺序放置。你目前正在加密你的IV,而IV应该放在密文前面,很明显。
IV在加密之前与纯文本进行异或运算。现在,这意味着您将纯文本清零:您正在加密一个零值块。
CipherMode.ECB模式似乎没有接收IV参数(这意味着无论您传入什么IV,结果都是一样的),这是可能的,因为ECB不需要作为初始向量的概念,因为也没有后续向量。如果你想屏蔽你的ECB块,在加密可以之前手动对你的块进行异或。当您更改为CipherMode.CBC时,IV确实很重要,因为后续块将与前一个加密块异或,形成一个链。