指定的初始化向量(IV)与此算法的块大小不匹配。

40

我正在研究一种基础的加密方法,使用RijndaelManaged算法。代码来自很久以前的某个地方,但我现在记不起来了。

之前我的代码是可以工作的,但是最近出了些问题,我无法确定原因。

当我运行代码时,会得到以下错误:

指定的初始化向量(IV)与此算法的块大小不匹配。

这是我的代码:

string textToEncrypt = "TEST STRING";

int keySize = 256;
string hashAlgorithm = "SHA1";
string passPhrase = "AH!PSB0%FGHR$";
string saltValue = "LRT%YUR#VBNL@1";
string initVector = "HR$2pIjHR$2pIj";

byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);

byte[] plainTextBytes = Encoding.UTF8.GetBytes(textToEncrypt);

var password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, 2);

byte[] keyBytes = password.GetBytes(keySize / 8);

RijndaelManaged symmetricKey = new RijndaelManaged();

symmetricKey.Mode = CipherMode.CBC;

ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes,initVectorBytes);

MemoryStream memoryStream = new MemoryStream();

var cryptoStream = new CryptoStream(memoryStream,encryptor,CryptoStreamMode.Write);
cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

cryptoStream.FlushFinalBlock();

byte[] cipherTextBytes = memoryStream.ToArray();

memoryStream.Close();
cryptoStream.Close();

string cipherText = Convert.ToBase64String(cipherTextBytes);

非常感谢您的帮助。


在德语中,这个错误信息的内容是:“指定的初始化向量(IV)与此算法的块大小不匹配”。 - Uwe Keim
3个回答

74
问题在于你的初始化向量大小需要是16字节。
你的初始向量大小是14字节。
你需要增加2个字节的初始向量大小,然后你的代码将正常工作。
示例:
string initVector = "HR$2pIjHR$2pIj12";
你将会得到你当前代码和提供的 IV(初始化向量)大小的输出: 本文提供了一个很好的解释,说明什么是初始化向量。 http://en.wikipedia.org/wiki/Initialization_vector

哦,这就是它!非常感谢您的帮助。 - Vladimir Kozhedubov

17

你应该能够使用以下方法检查IV需要多少字节:

algorithm.BlockSize / 8

BlockSize以比特为单位,因此128位/8会得到16个ASCII字节,并且您可能还会发现Rfc2898DeriveBytes是生成密钥的有用类。

algorithm.IV = rfc2898DeriveBytesForIV.GetBytes(algorithm.BlockSize / 8);

希望能对你有所帮助。


6
如果有人将他们的代码从.NET Framework迁移到.NET Core,并在RijndaelManaged.CreateEncryptor中开始收到此异常:你的旧代码之所以能够工作,是因为“.NET Framework允许大于64位的IV并截断它们”。
解决方法请参考Kevin Jones的评论:“只需将您的IV更改为仅限前8个字节即可”。
因此,举个例子:
private static byte[] IV_192 =  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 };

would become:

// Rename field if desired.
private static byte[] IV_192 =  { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

值得注意的是,“Rijndael”类是“Aes”算法的前身,应该使用“Aes”算法而非“Rijndael”。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接