2012-11-13 22 views
5

我試圖使用CBC模式的AES算法加密我的數據。爲此,我使用.Net Library'Bouncy Castle'。我沒有加密背景,所以我試圖直接使用它。這裏是我的加密代碼如何在用bouncyCastle加密之前填充數據

public byte[] encrypt(byte[] key, byte[] iv,byte[] data) 
    { 
     IBlockCipher engine=new AesFastEngine(); 
     KeyParameter keyParam = new KeyParameter(key); 
     CbcBlockCipher cipher = new CbcBlockCipher(engine); 

     ICipherParameters parameters = new ParametersWithIV(keyParam, iv); 

     byte[] output=new byte[16+data.Length]; 
     cipher.Init(true, parameters); 
     cipher.ProcessBlock(data, 0, output, data.Length); 

     //process output 
     byte[] cipherArray = new byte[data.Length]; 
     /* 
     int k=0; 
     for (int i = 0; i < output.Length; i++) 
     { 
      if (output[i]!= 0) 
      { 
       cipherArray[k++] = output[i]; 
      } 
     } 
     */ 
     return cipherArray; 

    } 

當我嘗試一個不是16的乘法的輸入時,我得到一個異常。當我用左邊的零填充數組(16長度爲16)的數組時,我可以得到結果。但結果對我來說也是一個問題。它給了我這樣的結果:

[0][0][0][0[111][22][33][44][66][77][33][12][32][23][0][0][0][0][0] 

左右兩邊的零。

我認爲這可能與我使用ProcessBlock(data, 0, output, data.Length)函數有關。我假設輸出是我的加密文本,但它似乎輸出應該比輸入長度更長。因爲我沒有關於這個功能的文檔,所以我可能會以錯誤的方式使用它。任何幫助將是應用程序

回答

4

充氣城堡會做填充你,開始你需要設置你的cihper爲:

PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CbcBlockCipher(engine), new Pkcs7Padding()); 

爲了您的代碼的其餘部分工作將需要使用cipher.GetOutputSize(data.Length)ProcessBytes,並DoFinal所以填充已正確添加。

byte[] output = new byte[cipher.GetOutputSize(data.Length)]; 
int len = cipher.ProcessBytes(data, 0, data.Length, output, 0); 
cipher.DoFinal(output, len); 

我有使用AES-GCM in Bouncy Castle on CodeReview

AES-GCM增加了認證加密的一個簡單的例子,但使用API​​的基本原理是相同的。

我也有高級加密框架,Kecyzar的C#端口,我用充氣城堡作爲後端,雖然這是一個更難例如,抽象加密代碼SymmetricStream是設置在BouncyAesKey

+0

使用AES-CBC謝謝jbtule,但是當我嘗試使用paddedCipher.DoFinal(output,len)時,我遇到了這個問題:它拋出一個異常「最後一個塊在描述中不完整」,processBytes方法返回的值是一個小於數據長度的16的乘積,你知道是什麼原因導致了這個問題嗎?謝謝 – ikbal

+0

@paskalnikov我添加了更多的代碼來展示如何使用。'ProcessBytes'將爲每個完整的塊輸出字節,並保留其餘的緩衝區(你也可以多次調用'ProcessBytes',一次給它一部分數據),它不會假設你已經完成了直到你調用'DoFinal',然後'DoFinal'將寫出最後一個字節(帶填充),所以如果你有'DoFinal'寫入你的最終輸出數組,你需要給它一個它應該寫入的位置的索引陣列。 – jbtule

2

通常會使用標準的填充算法來確保明文數據與密碼塊大小對齊。

您正在使用手寫編碼zero padding。這不是一個好的選擇,因爲它禁止以零字節結尾的原始數據 - 你如何區分這種填充?

我會建議你使用標準填充,如PKCS #7 padding。請注意,這通常被稱爲「PKCS#5填充」,因爲它們非常相似。

有關使用標準填充的示例,您可能希望參考另一個SO問題 - Encrypt/Decrypt using Bouncy Castle in C#