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

Posted

技术标签:

【中文标题】指定的初始化向量 (IV) 与此算法的块大小不匹配【英文标题】:Specified initialization vector (IV) does not match the block size for this algorithm 【发布时间】:2010-10-30 23:57:36 【问题描述】:

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

任何帮助将不胜感激。

【问题讨论】:

在德语中,此错误消息显示为:“Der angegebene Initialisierungsvektor (IV) entspricht nicht der Blockgröße für diesen Algorithmus”。 【参考方案1】:

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

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

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

例子:

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

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

hAC8hMf3N5Zb/DZhFKi6Sg==

这篇文章很好地解释了初始化向量是什么。

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

【讨论】:

天哪,就是这样!非常感谢您的帮助。【参考方案2】:

您应该能够检查 IV 需要使用多少字节:

algorithm.BlockSize / 8

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

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

希望对你有帮助。

【讨论】:

【参考方案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.”

【讨论】:

以上是关于指定的初始化向量 (IV) 与此算法的块大小不匹配的主要内容,如果未能解决你的问题,请参考以下文章

如何为 AES/CTR/NoPadding 选择合适的 IV(初始化向量)?

密码学之DES/AES算法

我该如何生成初始化向量?

随机数在密码学中的作用

AES128 CBC模式加密中初始化向量IV怎么设定?

Node.js 加密密钥和 iv 匹配 java SecretKeySpec / IvParameterSpec