![](/img/trans.png)
[英]Specified initialization vector (IV) does not match the block size in c# using AES
[英]C# Can't generate initialization vector 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)与该算法的块大小不匹配。
我要去哪里错了?
谢谢
初始化向量的大小必须与块大小匹配-如果是TripleDES,则为64位。 您的初始化向量比8个字节长得多。
此外,您实际上应该使用诸如PBKDF2之类的密钥派生功能从密码短语创建强密钥和初始化向量。
IV必须与tripDES.BlockSize
相同的长度(以位为tripDES.BlockSize
。 对于TripleDES,这将是8个字节(64位)。
密钥应为24个字节,IV应为8个字节。
tripDES.Key = Encoding.ASCII.GetBytes("123456789012345678901234");
tripDES.IV = Encoding.ASCII.GetBytes("12345678");
我已经在这里投票了所有答案(以及我之前的答案!),因为它们都是正确的。
但是,您正在犯一个更大的错误(我在v.early上犯了一个错误)-不要使用字符串来播种IV或密钥!
编译时字符串文字是unicode字符串,尽管事实上您不会得到随机的或足够宽的字节值扩展(因为即使随机字符串也包含很多重复的字节,这是因为它的字节范围很窄), ,实际上得到一个需要2个字节而不是1个字节的字符非常容易-尝试在键盘上使用一些更奇特的字符中的8个,您会明白我的意思-当转换为字节时,您最终可以超过8个字节。
好的-您正在使用ASCII编码-但这不能解决非随机问题。
相反,您应该使用RNGCryptoServiceProvider初始化IV和密钥,并且,如果您需要为此捕获一个常量值以备将来使用,则仍应使用该类-但应将结果捕获为十六进制字符串或Base-64编码值(我更喜欢十六进制)。
为了简单地实现此目的,我编写了一个在VS中使用的宏(绑定到键盘快捷键CTRL + SHIFT + G,CTRL + SHIFT + H ),该宏使用.Net PRNG生成十六进制字符串:
Public Sub GenerateHexKey()
Dim result As String = InputBox("How many bits?", "Key Generator", 128)
Dim len As Int32 = 128
If String.IsNullOrEmpty(result) Then Return
If System.Int32.TryParse(result, len) = False Then
Return
End If
Dim oldCursor As Cursor = Cursor.Current
Cursor.Current = Cursors.WaitCursor
Dim buff((len / 8) - 1) As Byte
Dim rng As New System.Security.Cryptography.RNGCryptoServiceProvider()
rng.GetBytes(buff)
Dim sb As New StringBuilder(CType((len / 8) * 2, Integer))
For Each b In buff
sb.AppendFormat("{0:X2}", b)
Next
Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection
Dim editPoint As EnvDTE.EditPoint
selection.Insert(sb.ToString())
Cursor.Current = oldCursor
End Sub
现在您需要做的就是将十六进制字符串文字转换为字节数组-我使用一种有用的扩展方法来做到这一点:
public static byte[] FromHexString(this string str)
{
//null check a good idea
int NumberChars = str.Length;
byte[] bytes = new byte[NumberChars / 2];
for (int i = 0; i < NumberChars; i += 2)
bytes[i / 2] = Convert.ToByte(str.Substring(i, 2), 16);
return bytes;
}
可能有更好的方法可以做到这一点-但这对我有用。
我这样做是这样的:
var derivedForIv = new Rfc2898DeriveBytes(passwordBytes, _saltBytes, 3);
_encryptionAlgorithm.IV = derivedForIv.GetBytes(_encryptionAlgorithm.LegalBlockSizes[0].MaxSize / 8);
IV使用算法本身通过LegalBlockSizes属性描述的块大小从派生字节'smusher'中获取字节。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.