2011-06-19 38 views
1

當運行該代碼的「加密後的字符串:」印刷在控制檯上的每個I運行時間是不同的。即,加密和解密模式是AES/CBC/ISO10126Padding然而加密的字符串沒有成功地解密。 當我運行在「AES」模式相同的代碼的「加密後的字符串:」印刷在控制檯上是每次相同。請你能告訴我,爲什麼在AES/CBC的情況下/ ISO10126Padding輸出每個我運行它時diff的。問題與AES/CBC/ISO10126Padding模式

import java.io.FileOutputStream; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import java.sql.Connection; 
import java.sql.PreparedStatement; 
import java.sql.ResultSet; 
import java.sql.SQLException; 

import javax.crypto.Cipher; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 



//import org.apache.log4j.Logger; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.bouncycastle.util.encoders.Base64; 


public class AES_Encrypt_Decrypt_Bouncy_Castle { 

    public static SecretKeySpec getKey() { 
     try { 
      String keyFromfile = "ZoyNMZzsOYh7BxwcgJseBji95hmVTlgKe/9KFY44Jzg="; 

      byte[] keyBytes = Base64.decode(keyFromfile.getBytes()); 
      byte[] finalKeyBytes = new byte[32]; 

      for (int i = 0; i < 32; i++) { 
       finalKeyBytes[i] = keyBytes[i]; 
      } 
      System.out.println("keyBytes="+keyBytes.length); 
      System.out.println("Key is "+ keyBytes); 
      for(int j=32;j<keyBytes.length;j++){ 
       System.out.println("keyBytes="+keyBytes[j]); 
      }   
      SecretKeySpec skeySpec = new SecretKeySpec(finalKeyBytes, "AES"); 
      return skeySpec; 
     } catch (Exception e) { 
      return null; 
     } 

    } 


    public static void main(String[] args) throws Exception { 

     SecretKeySpec skeySpec = getKey(); 
     byte [] iv = Base64.decode("AWNCK2F/9llI0Rs+dQB36Q=="); 
     IvParameterSpec initializationVector = new IvParameterSpec(iv); 
     Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding", new BouncyCastleProvider()); 
     cipher.init(Cipher.ENCRYPT_MODE, skeySpec, initializationVector); 
     String message = "Brian12345678"; 
     byte[] encrypted = cipher.doFinal(message.getBytes()); 
     System.out.println("Decoded plain text = "+new String (encrypted)); 
     byte[] encodedEncryptedText = Base64.encode(encrypted); 
     System.out.println("encrypted string: " + new String (encodedEncryptedText)); 
     Cipher cipher2 = Cipher.getInstance("AES/CBC/ISO10126Padding", new BouncyCastleProvider()); 
     cipher2.init(Cipher.DECRYPT_MODE, skeySpec,initializationVector); 
     byte[] original = cipher2.doFinal(Base64.decode(encodedEncryptedText)); 
     String originalString = new String(original); 
     System.out.println("Original string: " + originalString); 

    } 

} 

回答

2

the wikipedia padding page

ISO 10126(抽出,2007 [2] [3])指定的填補應在用隨機字節即最後塊的結束來完成,和填充邊界應由最後一個字節指定。

這可以解釋爲什麼加密數據不同,但可以成功解密。

+0

如果它只是在過去的16個字節是不同的,這應該是你的答案。如果你希望它是相同的使用PKCS#5填充。這是同樣的,但它使用的填充邊界字節(使用相同的字)的所有字節。因此,填充Oracle攻擊可能更容易。請確保您的加密數據具有適當的完整性檢查,例如使用HMAC。 –