C#无法生成初始化向量IV
当我尝试为 TripleDES 加密器创建 IV 初始化向量时,出现以下错误。
请看代码示例:
TripleDESCryptoServiceProvider tripDES = new TripleDESCryptoServiceProvider();
byte[] key = Encoding.ASCII.GetBytes("SomeKey132123ABC");
byte[] v4 = key;
byte[] connectionString = Encoding.ASCII.GetBytes("SomeConnectionStringValue");
byte[] encryptedConnectionString = Encoding.ASCII.GetBytes("");
// Read the key and convert it to byte stream
tripDES.Key = key;
tripDES.IV = v4;
这是我从VS得到的异常。
指定的初始化向量 (IV) 与该算法的块大小不匹配。
我哪里出错了?
谢谢
I get the following error when I try to create a IV initialization vector for TripleDES encryptor.
Please see the code example:
TripleDESCryptoServiceProvider tripDES = new TripleDESCryptoServiceProvider();
byte[] key = Encoding.ASCII.GetBytes("SomeKey132123ABC");
byte[] v4 = key;
byte[] connectionString = Encoding.ASCII.GetBytes("SomeConnectionStringValue");
byte[] encryptedConnectionString = Encoding.ASCII.GetBytes("");
// Read the key and convert it to byte stream
tripDES.Key = key;
tripDES.IV = v4;
This is the exception that I get from the VS.
Specified initialization vector (IV) does not match the block size for this algorithm.
Where am I going wrong?
Thank you
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
MSDN 明确声明:
对于 Triple DES,它是 64 位。
MSDN explicitly states that:
For Triple DES it is 64 bits.
初始化向量的大小必须与块大小匹配 - 在 TripleDES 的情况下为 64 位。您的初始化向量比八个字节长得多。
此外,您应该真正使用密钥派生函数,例如 PBKDF2 从密码短语创建强密钥和初始化向量。
The size of the initialization vector must match the block size - 64 bit in case of TripleDES. Your initialization vector is much longer than eight bytes.
Further you should really use a key derivation function like PBKDF2 to create strong keys and initialization vectors from password phrases.
Key 应为 24 字节,IV 应为 8 字节。
Key should be 24 bytes and IV should be 8 bytes.
IV 的长度(以位为单位)必须与 tripDES.BlockSize 相同。对于 TripleDES,这将是 8 个字节(64 位)。
The IV must be the same length (in bits) as
tripDES.BlockSize
. This will be 8 bytes (64 bits) for TripleDES.我在这里对每个答案都投了赞成票(以及在我之前的答案!),因为它们都是正确的。
然而,你犯了一个更大的错误(我早期也犯过这个错误)——不要使用绳子来播种 IV 或钥匙!
编译时字符串文字是一个 unicode 字符串,尽管事实上您不会获得随机或足够广泛的字节值(因为即使是随机字符串也包含大量重复字节,因为字节范围很窄)可打印字符),很容易得到一个实际上需要 2 个字节而不是 1 个字节的字符 - 尝试在键盘上使用 8 个更奇特的字符,你就会明白我的意思 - 当转换为字节时,你最终可以得到超过8个字节。
好的 - 所以你正在使用 ASCII 编码 - 但这并不能解决非随机问题。
相反,您应该使用 RNGCryptoServiceProvider 来初始化您的 IV 和 Key,如果您需要为此捕获一个常量值以供将来使用,那么您仍然应该使用该类 - 但将结果捕获为 hex 字符串或 Base-64 编码值(不过我更喜欢十六进制)。
为了简单地实现这一点,我编写了一个在 VS 中使用的宏(绑定到键盘快捷键 CTRL+SHIFT+G、CTRL+SHIFT+H),它使用 .Net PRNG 生成一个十六进制字符串:
现在您需要做的就是将十六进制字符串文字转换为字节数组 - 我使用一个有用的扩展方法来做到这一点:
可能有更好的方法来做到这一点 - 但它对我有用。
I've upvoted every answer (well the ones that are here before mine!) here as they're all correct.
However there's a bigger mistake you're making (one which I also made v.early on) - DO NOT USE A STRING TO SEED THE IV OR KEY!!!
A compile-time string literal is a unicode string and, despite the fact that you will not be getting either a random or wide-enough spread of byte values (because even a random string contains lots of repeating bytes due to the narrow byte range of printable characters), it's very easy to get a character which actually requires 2 bytes instead of 1 - try using 8 of some of the more exotic characters on the keyboard and you'll see what I mean - when converted to bytes you can end up with more than 8 bytes.
Okay - so you're using ASCII Encoding - but that doesn't solve the non-random problem.
Instead you should use RNGCryptoServiceProvider to initialise your IV and Key and, if you need to capture a constant value for this for future use, then you should still use that class - but capture the result as a hex string or Base-64 encoded value (I prefer hex, though).
To achieve this simply, I've written a macro that I use in VS (bound to the keyboard shortcut CTRL+SHIFT+G, CTRL+SHIFT+H) which uses the .Net PRNG to produce a hex string:
Now all you need to do is to turn your hex string literal into a byte array - I do this with a helpful extension method:
There are probably better ways of doing that bit - but it works for me.
我这样做是这样的:
IV 使用算法本身通过 LegalBlockSizes 属性描述的块大小从派生字节“smusher”获取字节。
I do it like this:
The IV gets bytes from the derive bytes 'smusher' using the block size as described by the algorithm itself via the LegalBlockSizes property.