C#无法生成初始化向量IV [英] C# Can't generate initialization vector IV

查看:285
本文介绍了C#无法生成初始化向量IV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试为TripleDES加密器创建IV初始化向量时,会出现以下错误。

I get the following error when I try to create a IV initialization vector for TripleDES encryptor.

请参阅代码示例:

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获得的例外。

This is the exception that I get from the VS.

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

谢谢

推荐答案

但是你有一个更大的错误(一个更大的错误,我也使用v.early) - 不要使用一个字符串来获得IV或键!

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!!!

编译时字符串字面量是一个unicode字符串,尽管事实上你不会得到一个随机或足够广泛的字节值(因为即使一个随机字符串包含大量的重复字节,由于可打印字符的窄字节范围),很容易得到一个字符实际上需要2个字节而不是1 - 尝试使用8个键盘上更奇怪的字符,你会看到我的意思 - 当转换为字节,你可以结束多于8字节。

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.

好的,所以你使用ASCII编码,但这不解决非随机问题。

Okay - so you're using ASCII Encoding - but that doesn't solve the non-random problem.

RNGCryptoServiceProvider初始化您的IV和键,如果您需要捕获一个常量值供将来使用,那么您仍然应该使用该类 - 但捕获结果作为十六进制字符串或Base-64编码的值(我喜欢十六进制,虽然)。

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).

为了实现这个简单,我写了一个我在VS中使用的宏(绑定到键盘快捷方式 CTRL + SHIFT + G,CTRL + SHIFT + H ),它使用.Net PRNG产生十六进制字符串:

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:

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

现在你所需要做的就是将十六进制字符串文字转换为字节数组 - 这有一个有用的扩展方法:

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:

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

这可能是更好的方法,但它适用于我。

There are probably better ways of doing that bit - but it works for me.

这篇关于C#无法生成初始化向量IV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆