2010-06-10 74 views
6

我在编程方面颇为新颖。为了提示用户输入密码来加密文件,我编写了下面的代码,但它在密码长度为8时才起作用,我能做什么为了接受任何数量的密码字符?使用rijndael的加密

string pass = textBox2.Text.ToString(); 
      string password = @"" + pass + ""; 
      UnicodeEncoding UE = new UnicodeEncoding(); 
      byte[] key = UE.GetBytes(password); 


      FileStream fsCrypt = new FileStream(@"c:\\users\\new", FileMode.Create); 
      name = fsCrypt.Name; 
      RijndaelManaged RMCrypto = new RijndaelManaged(); 

      CryptoStream cs = new CryptoStream(fsCrypt, 
       RMCrypto.CreateEncryptor(key, key), 
       CryptoStreamMode.Write); 

      FileStream fsIn = new FileStream(filename, FileMode.Open); 

      int data; 
      while ((data = fsIn.ReadByte()) != -1) 
       cs.WriteByte((byte)data); 
+0

我有点用线不解:字符串密码= @“” +传+“”;你想通过在字符串的每一端连接一个空字符串来实现什么,从而产生一个相同的字符串。 – 2010-06-10 10:48:19

回答

1

只有在GetBytes()的结果是合法的KeySize的情况下,才能直接从Encoding.GetBytes()获得密码。

更重要的是,它使得Key非常脆弱,特别是当您选择Unicode编码时。 “foobar”密钥中的字节模式为66 00 6F 00 6F 00 62 00 61 00 72 00。你看到所有的00字节吗?

官方的方法是使用Rfc2898DeriveBytes类。另外,使用Key作为IV可能不是一个好主意,我对此并不完全确定。

另见this SO question

+0

感谢提到它,是的,你是对的,它是一个弱者。 – Mohammad 2010-06-10 10:27:36

+0

将密钥重用为IV确实是一个糟糕的主意。我在这里写了:http://crazyscot.livejournal.com/304065.html – crazyscot 2010-06-10 10:53:59

+0

@crazyscot:是的,thx为链接。但请注意,在避免传输Salt和IV的开销的同时加密短字符串是可以接受的。但它应该明确标记和理解为弱。 – 2010-06-10 11:23:07

2

你需要的是会从您的密码获取Rijndael算法的有效密钥长度的函数,而在那一刻,你的UnicodeEncoding.GetBytes使用只会给这个密码的某些离散的长度,如您我发现了。

您应该使用另一个函数从密码中获取密钥 - 可能需要获取已生成的字节数组,然后运行SHA1等密码哈希函数。 SHA1会给你一个128位的长度,就像你当前的8个字符的密码一样,但是不管密码的长度。

+0

让我看看我做对了吗? 你的意思是我应该把密码的哈希值(肯定是足够长的),然后通过它作为密钥? – Mohammad 2010-06-10 10:17:31

+0

@user ####:是的。 – 2010-06-10 10:19:32

0

退房PasswordDeriveBytes

http://msdn.microsoft.com/en-us/library/system.security.cryptography.passwordderivebytes(v=VS.100).aspx

你需要一个固定的盐值以及所传递的,这将停止人们从算法的工作出了密码。

它这样使用的TripleDES的,应该很容易修改为Rijndael算法:

// Create a TripleDESCryptoServiceProvider object. 
TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider(); 

// Create a PasswordDeriveBytes object and then create 
// a TripleDES key from the password and salt. 
PasswordDeriveBytes pdb = new PasswordDeriveBytes(pwd, salt); 


// Create the key and set it to the Key property 
// of the TripleDESCryptoServiceProvider object. 
tdes.Key = pdb.CryptDeriveKey("TripleDES", "SHA1", 192, tdes.IV);