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

时间:2009-06-03 13:44:15

标签: c# encryption rijndaelmanaged rijndael

我正在研究基本加密方法。我正在使用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);

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:56)

问题是你的初始化向量大小需要是16个字节。

您的初始矢量大小为14个字节。

您需要将初始向量的大小增加2个字节,然后您的代码才能正常工作。

示例:

string initVector = "HR$2pIjHR$2pIj12";

然后,您将获得当前代码和提供的示例IV(初始化向量)大小的输出:

hAC8hMf3N5Zb / DZhFKi6Sg ==

本文提供了有关初始化向量的详细说明。

http://en.wikipedia.org/wiki/Initialization_vector

答案 1 :(得分:12)

您应该能够检查IV需要使用的字节数:

algorithm.BlockSize / 8

BlockSize是以位为单位,因此128位/ 8给出了16个字节的ASCII,你也可以找到Rfc2898DeriveBytes一个用于生成密钥的有用类。

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

希望它有所帮助。

答案 2 :(得分:3)

如果有人将其代码从.NET框架迁移到.NET Core并开始在RijndaelManaged.CreateEncryptor上遇到此异常:由于“ .NET Framework allows IVs greater than 64 bits and truncates them”这一事实,您的旧感冒一直在起作用。

要解决,请参见Kevin Jones评论:“ simply change your IV to only the first 8 bytes

因此,例如:

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 };

将成为:

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

也值得注意的是“ Rijndael class is the predecessor of the Aes algorithm. You should use the Aes algorithm instead of Rijndael.