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)与此算法的块大小不匹配。

我哪里错了?

谢谢

我赞成了每一个答案(以及那些在我之前的答案!),因为它们都是正确的。

然而,你正在制造一个更大的错误(我也做了一个错误) – 不要使用一个字符串来播种IV或关键!

编译时字符串文字是一个unicode字符串,尽管你不会得到一个随机或足够宽的字节值扩展(因为即使一个随机字符串包含大量的重复字节,因为字节范围很窄可打印的字符),很容易得到一个实际上需要2个字节而不是1个字符的字符 – 尝试使用键盘上一些更奇特的字符中的8个,你会看到我的意思 – 当转换为字节时你可以结束超过8个字节。

好的 – 所以你正在使用ASCII编码 – 但这并不能解决非随机问题。

相反,你应该使用RNGCryptoServiceProvider初始化你的IV和Key,如果你需要捕获一个常量值以备将来使用,那么你仍然应该使用该类 – 但是将结果捕获为hex字符串或Base-64编码值(不过我喜欢hex。

为了简单地实现这一点,我编写了一个我在VS中使用的宏(绑定到键盘快捷键CTRL + SHIFT + G,CTRL + SHIFT + H ),它使用.Net PRNG生成hex字符串:

 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 

现在您需要做的就是将hex字符串文字转换为字节数组 – 我使用一个有用的扩展方法:

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

这样做可能有更好的方法 - 但它对我有用。

MSDN明确声明 :

… IV属性的大小必须与BlockSize属性相同。

对于Triple DES,它是64位。

初始化向量的大小必须与块大小匹配 – 在TripleDES的情况下为64位。 初始化向量比8个字节长得多。

此外,您应该使用密钥派生函数(如PBKDF2)从密码短语创建强密钥和初始化向量。

密钥应为24字节,IV应为8字节。

 tripDES.Key = Encoding.ASCII.GetBytes("123456789012345678901234"); tripDES.IV = Encoding.ASCII.GetBytes("12345678"); 

IV必须与tripDES.BlockSize具有相同的长度(以位为tripDES.BlockSize 。 对于TripleDES,这将是8个字节(64位)。

我是这样做的:

 var derivedForIv = new Rfc2898DeriveBytes(passwordBytes, _saltBytes, 3); _encryptionAlgorithm.IV = derivedForIv.GetBytes(_encryptionAlgorithm.LegalBlockSizes[0].MaxSize / 8); 

IV使用块大小从派生字节’smusher’获取字节,如算法本身通过LegalBlockSizes属性所描述的。