2014-05-19 37 views
2

在我的Windows Phone 8應用程序中,我需要使用DESede/CBC/PKCS5Padding和PBKDF2密鑰對數據進行加密 - 解密。
我發現瞭如何使用Bouncy Castle進行加密的示例:
http://www.go4expert.com/articles/bouncy-castle-net-implementation-triple-t24829/
我能夠加密我的數據(文本),但我無法使用此代碼解密我的加密數據。 當我試圖調用DoFinal()時,它會拋出異常「pad block corrupted」。
也許我錯過了一些解密的東西?
也許有人知道使用DESede/CBC/PKCS5Padding與PBKDF2密鑰進行加密的Windows Phone 8上的替代庫(方式)?C#Bouncy Castle不解密,例外:填充塊損壞

using Raksha.Crypto; 
using Raksha.Crypto.Engines; 
using Raksha.Crypto.Modes; 
using Raksha.Crypto.Paddings; 
using Raksha.Crypto.Parameters; 
using System; 
using System.Security.Cryptography; 
using System.Text; 

namespace MyNamespace 
{ 
    class EncryptDecrypt 
    { 
     Rfc2898DeriveBytes key; 
     BufferedBlockCipher cipherEncrypt; 
     BufferedBlockCipher cipherDecrypt; 
     private readonly int ITERACTIONCOUNT = 1000; 
     private readonly int KEY_LENGTH = 24; 

     public EncryptDecrypt(string passPhrase, string salt) 
     { 
      byte[] SALT = Encoding.UTF8.GetBytes(salt); 
      key = new Rfc2898DeriveBytes(passPhrase, SALT, ITERACTIONCOUNT); 

      DesEdeEngine desede = new DesEdeEngine(); 

      cipherEncrypt = new PaddedBufferedBlockCipher(new CbcBlockCipher(desede)); 
      cipherDecrypt = new PaddedBufferedBlockCipher(new CbcBlockCipher(desede)); 
      DesEdeParameters p = new DesEdeParameters(key.GetBytes(KEY_LENGTH)); 

      cipherEncrypt.Init(true, p); 
      cipherDecrypt.Init(false, p); 
     } 

    public byte[] Encrypt(byte[] dataToEncrypt) 
     { 
      try 
      { 
       byte[] outbytes = cipherEncrypt.DoFinal(dataToEncrypt); 
       return outbytes; 
      } 
      catch(Exception ex) 
      { 
       System.Diagnostics.Debug.WriteLine("Encrypt() Exception: " + ex.Message); 
       return new byte[] { 0 }; 
      } 
     } 

     public byte[] Decrypt(byte[] dataToDecrypt) 
     { 
      try 
      { 
       byte[] result = cipherDecrypt.DoFinal(dataToDecrypt); 
       return result; 
      } 
      catch(CryptoException ex) 
      { 
       System.Diagnostics.Debug.WriteLine("Decrypt() Exception: " + ex.Message); 
     // ex.Message: pad block corrupted 
       return new byte[] { 0 }; 
      } 
     } 
    } 
+0

您是否以某種方式在某處存儲或傳輸密文(加密函數的輸出)? –

+0

@owlstead在這種情況下,我只是把加密的字節解密函數沒有任何改變(測試),如:加密解密加密=新的加密解密(「000000」,「Adobe Photoshop」); byte [] encrypted = encrypt.Encrypt(Encoding.UTF8.GetBytes(「some text」)); byte [] decrypted = encrypt.Decrypt(encrypted);並且,當我在解密函數中調用DoFinal()時,它會拋出異常「pad block corrupted」 – tsiganoff

+0

嗯,雖然我不知道'Raksha.Crypto'是什麼,但我卻難倒了。 –

回答

2

我解決了這個問題!
必須使用第一個參數true來初始化DesEdeEngine。

DesEdeEngine desede = new DesEdeEngine(); 
desede.Init(true, key); 

我不知道爲什麼,但它是我用DesEdeEngine的同一對象的密碼解密簡化版,此事。

簡而言之,默認情況下,DesEdeEngine被初始化爲解密器,而不是加密它的解密塊填充字節。並且當DoFinal()中的PaddedBufferedBlockCipher調用PadCount(),其中最後一個字節的值必須> 0並且< 8我得到的值如48或123或類似的東西,它拋出了一個異常「pad block corrupted」。

感謝所有參與者。

1

有很多事情會導致「Bad Padding」錯誤。基本上任何導致最後一個塊的末尾不符合預期填充的東西都會拋出錯誤。可能的原因包括:不正確的填充設置,不正確的密鑰,損壞的密文等。

要嘗試診斷問題,請將解密端設置爲NoPadding。這將接受任何東西,並允許您檢查輸出:

  • 完整垃圾:您可能在鍵或不同模式設置中有錯誤。

  • 第一塊垃圾:您可能有關鍵錯誤或IV錯誤。

  • 最後一塊垃圾:可能是破譯的文件結尾。

  • 一個正確的解密與一些奇怪的字節之後:奇怪的字節是填充。

如果它真的只是填充,那麼設置解密函數以期望那種填充。否則檢查密鑰/ IV /密文是否爲字節對字節對於加密和解密都是相同的。

這是重要您設置了診斷後的填充模式。 NoPadding是不安全的。

在你的代碼的情況下,我看不到你設置PKCS5填充的位置。我假設CBC模式在CbcBlockCipher(desede)內部設置。

相關問題