2013-02-22 173 views
1

我试图用c#制作加密系统。这是加密的代码。现在指定的初始化向量(IV)与此算法的块大小不匹配

public static void EncryptFile(string inFile, string outFile, string @inkey) 
    { 
     try 
     { 
      UnicodeEncoding ue = new UnicodeEncoding(); 
      byte[] key = ue.GetBytes(inkey); 
      FileStream fsEncrypt = new FileStream(outFile, FileMode.Create); 

      RijndaelManaged rmCrypto = new RijndaelManaged(); 

      CryptoStream cs = new CryptoStream(fsEncrypt, rmCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write); 
      FileStream fsIn = new FileStream(inFile, FileMode.Open); 

      int data; 
      while((data=fsIn.ReadByte()) != 1){ 
       cs.WriteByte((byte)data); 
      } 

      fsIn.Close(); cs.Close(); fsEncrypt.Close(); 
     } 
     catch(Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Fail to encrypt", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

,这个代码抛出异常,我每次运行它的时候,说

指定的初始化向量(IV)不为 这种算法

我的块大小匹配请阅读有关此问题的其他讨论,并说明字节数有问题(传递给此函数的密钥长度为255)。但我已经尝试使关键字只有16个字节,仍然无法正常工作。

一些故障排除我发现了这一部分之后:

CryptoStream cs = new CryptoStream(fsEncrypt, rmCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write);

抛出异常。我不知道为什么。任何人都可以帮忙

+1

我没听说过255位密钥。也许尝试256? – 2013-02-22 07:53:19

+1

btw。直接使用密码作为密钥不是一个好主意。您应该使用随机生成的二进制密钥(推荐除非您有用户输入的密码)或基于密码的密钥派生函数(昂贵)。 – CodesInChaos 2013-02-22 09:23:26

回答

4

您将密钥两次传递给CreateEncryptor,但它需要一个密钥和一个IV(Initialization Vector)。第二个参数应该是一个128个随机位的数组。 RijndaelManaged的默认块大小为128位,但它也接受其他值(如256)。有关更多信息,请阅读this。正如Grzegorz W在评论中指出的那样,您可能还需要选择different key size

如果您不熟悉加密(在这种情况下,您应该停止并在实施自己的解决方案之前了解更多信息,或者使用现成的解决方案),function of the IV可防止相同邮件编码两次产生相同的密文。对于每条消息(以及每条消息的使用)应该是随机的,不需要保密,但是你需要存储它以便能够稍后解密消息(即,在加密之后你不能丢弃它)。

+1

您的意思是128 *位* ...或16个字节。 – 2013-02-22 07:55:46

+0

@DuncanJones修,谢谢! – mgibsonbr 2013-02-22 07:58:27

+0

非常感谢,现在它工作! – user2002495 2013-02-22 08:19:53