2010-06-10 46 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);