2012-10-26 143 views
1

我試圖獲取此代碼進行加密和解密,但在.FlushFinalBlock()解密過程中,我一直收到的數據長度太長。使用Rijndael數據加密和解密太長

我不知道我在做什麼錯在這裏,因爲我在這個問題上超出了我的元素。

任何人都可以告訴我我在做什麼錯嗎?加密是可以的,但它不能解密它的加密。

static byte[] u8_Salt = new byte[] { 0x26, 0x19, 0x81, 0x4E, 0xA0, 0x6D, 0x95, 0x34, 0x26, 0x75, 0x64, 0x05, 0xF6 }; 

    public static string Encrypt(string data, string password) 
    { 
     // 
     Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt); 
     // 
     Rijndael i_Alg = Rijndael.Create(); 
     i_Alg.Padding = PaddingMode.None; 
     i_Alg.Key = pdb.GetBytes(32); 
     i_Alg.IV = pdb.GetBytes(16); 
     // 
     using (var cryptoProvider = new DESCryptoServiceProvider()) 
     using (var memoryStream = new MemoryStream()) 
     using (var cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateEncryptor(), CryptoStreamMode.Write)) 
     using (var writer = new StreamWriter(cryptoStream)) 
     { 
      writer.Write(data); 
      writer.Flush(); 
      cryptoStream.FlushFinalBlock(); 
      writer.Flush(); 
      return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length); 
     } 
    } 
    public static string Decrypt(string data, string password) 
    { 
     Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt); 
     // 
     Rijndael i_Alg = Rijndael.Create(); 
     i_Alg.Padding = PaddingMode.None; 
     i_Alg.Key = pdb.GetBytes(32); 
     i_Alg.IV = pdb.GetBytes(16); 
     // 
     using (var cryptoProvider = new DESCryptoServiceProvider()) 
     using (var memoryStream = new MemoryStream()) 
     using (var cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateDecryptor(), CryptoStreamMode.Write)) 
     using (var writer = new StreamWriter(cryptoStream)) 
     { 
      writer.Write(data); 
      writer.Flush(); 
      cryptoStream.FlushFinalBlock(); 
      writer.Flush(); 
      return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length); 
     } 
    } 
+0

夥計,這是完美的!愛這個擴展..謝謝 –

回答

3

您的代碼有幾個問題。首先,您正在創建一個Rijndael(AES)對象。但是,您使用DESCryptoServiceProvider這意味着您實際上使用DES,而不是Rijndael。由於這個原因,你也有問題,你沒有設置算法的關鍵。以下是使用RijndaelManaged算法重寫的兩個函數,該算法是.NET上的AES算法的管理實現。我測試過了,你可以加密和解密沒有問題。另外:不要使用鹽的價值,它遍佈互聯網。

static byte[] u8_Salt = new byte[] { 0x26, 0x19, 0x81, 0x4E, 0xA0, 0x6D, 0x95, 0x34, 0x26, 0x75, 0x64, 0x05, 0xF6 }; 

public static string EncryptString(string plainText, string password) 
{ 
    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt); 
    using (RijndaelManaged i_Alg = new RijndaelManaged { Key = pdb.GetBytes(32), IV = pdb.GetBytes(16) }) 
    { 
     using (var memoryStream = new MemoryStream()) 
     using (var cryptoStream = new CryptoStream(memoryStream, i_Alg.CreateEncryptor(), CryptoStreamMode.Write)) 
     { 
      byte[] data = Encoding.UTF8.GetBytes(plainText); 
      cryptoStream.Write(data, 0, data.Length); 
      cryptoStream.FlushFinalBlock(); 

      return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length); 
     } 
    } 
} 

public static string Decrypt(string cipherText, string password) 
{ 
    Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(password, u8_Salt); 

    using (RijndaelManaged i_Alg = new RijndaelManaged { Padding = PaddingMode.Zeros, Key = pdb.GetBytes(32), IV = pdb.GetBytes(16) }) 
    { 
     using (var memoryStream = new MemoryStream()) 
     { 
      using (var cryptoStream = new CryptoStream(memoryStream, i_Alg.CreateDecryptor(), CryptoStreamMode.Write)) 
      { 
       byte[] data = Convert.FromBase64String(cipherText); 
       cryptoStream.Write(data, 0, data.Length); 
       cryptoStream.Flush(); 

       return Encoding.UTF8.GetString(memoryStream.ToArray()); 
      } 
     } 
    } 
} 

隨機生成一個鹽我會用RNGCryptoServiceProvider,這將產生一個加密的安全隨機字節數組,你可以使用。您需要在單獨的過程中生成它並將其用作鹽。

+0

謝謝。是否有資源顯示如何選擇正確的鹽值? –

+0

我編輯了答案以添加關於生成隨機鹽的信息。 – nerdybeardo

+1

我希望對你說實話,就是用RNGCryptoServiceProvider生成一個隨機密鑰,而不是使用Rfc2898DeriveBytes。如果您使用隨機密鑰,我不認爲有這種需要。唯一需要做的事情是檢查輸出是否存在可能存在的弱密鑰。原因是Rfc2898DeriveBytes將使用Sha-1 HMAC使用您的密碼作爲密鑰,然後對salt進行哈希處理,因此您可能會減少密鑰空間,因爲Sha-1輸出160位,而AES最多可能需要256位密鑰。 – nerdybeardo

相關問題