当我尝试为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)与此算法的块大小不匹配。
我哪里错了?
谢谢
答案 0 :(得分:10)
答案 1 :(得分:6)
初始化向量的大小必须与块大小匹配 - 在TripleDES的情况下为64位。初始化向量比8个字节长得多。
此外,您应该使用密钥派生函数(如PBKDF2)从密码短语创建强密钥和初始化向量。
答案 2 :(得分:5)
IV必须与tripDES.BlockSize
的长度(以位为单位)相同。对于TripleDES,这将是8个字节(64位)。
答案 3 :(得分:5)
密钥应为24字节,IV应为8字节。
tripDES.Key = Encoding.ASCII.GetBytes("123456789012345678901234");
tripDES.IV = Encoding.ASCII.GetBytes("12345678");
答案 4 :(得分:4)
我赞成每一个答案(以及那些在我之前的答案!),因为它们都是正确的。
然而,你犯的是一个更大的错误(我也做了一个错误) - 不要使用一个字符串来制作IV或KEY !!!
编译时字符串文字是一个unicode字符串,尽管你不会得到一个随机或足够宽的字节值扩展(因为即使一个随机字符串包含大量的重复字节,因为它很窄可打印字符的字节范围),很容易得到一个实际上需要2个字节而不是1个字符的字符 - 尝试使用键盘上一些更奇特的字符中的8个,你会看到我的意思 - 转换为字节时你最终可能超过8个字节。
好的 - 所以你正在使用ASCII编码 - 但这并不能解决非随机问题。
相反,你应该使用RNGCryptoServiceProvider初始化你的IV和Key,如果你需要捕获一个常量值以备将来使用,那么你仍然应该使用该类 - 但是将结果捕获为 hex 字符串或Base-64编码值(我更喜欢hex)。
为了简单地实现这一点,我编写了一个我在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;
}
这样做可能有更好的方法 - 但它对我有用。
答案 5 :(得分:0)
我这样做:
var derivedForIv = new Rfc2898DeriveBytes(passwordBytes, _saltBytes, 3);
_encryptionAlgorithm.IV = derivedForIv.GetBytes(_encryptionAlgorithm.LegalBlockSizes[0].MaxSize / 8);
IV使用块大小从导出字节'smusher'获取字节,如算法本身通过LegalBlockSizes属性所描述的那样。