2011-07-21 42 views
2

我是Android開發者的新手,現在我在Android上實現了一個AES,它可以用用戶輸入密碼加密字符串。加密看起來很好,它可以省略Base64/Hex編碼的字符串。無法在Android上解密AES?

但是,當我試圖解密它時,問題就出現了:隨着解密,這個遺漏總是給我帶來一堆亂七八糟的字符。

爲了擺脫它,我試着通過在從字符串轉換爲byte []時定義一個字符集(如UTF-8)來調試它,但沒有命中,並且還嘗試使用base編碼omit 64或Hex,但兩者都失敗。

我也試過在使用cipher.getInstance方法時定義AES/CBC/PKCS5Padding或者只是AES,但仍然沒有去。

這是相當惱人的,你們可以幫我嗎?

忘了提,我曾經問過類似的問題https://stackoverflow.com/questions/6727255/aes-decryption-on-android-not-correct,那裏的語法問題已經糾正了。

而且下面的代碼:

加密

public String AESEncrypt(String sKey, String PlainMsg) 
       throws Exception { 
      //Try use some Android based alert dialog to catch this exception. 
      if (sKey == null) { 
       Log.e("SecureChat", "IllegalArgumentException Catched"); 
       throw new IllegalArgumentException ("NULL Secret NOT ALLOWED!"); 
      }   
      /*Old Method 
      //byte[] rawKey = getRawKey(sKey.getBytes("UTF-8")); 
      byte[] rawKey = getRawKey(sKey.getBytes()); 
      //Encrypt start 
      SecretKeySpec keySpec = new SecretKeySpec(rawKey, "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 
      cipher.init(Cipher.ENCRYPT_MODE, keySpec); 
      //byte[] cipherText = cipher.doFinal(PlainMsg.getBytes("UTF-8")); 
      byte[] cipherText = cipher.doFinal(PlainMsg.getBytes()); 
      return Base64Encoded(cipherText); 
      */ 
      //New Method 
      byte[] salt = getSalt(); 
      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC"); 
      KeySpec spec = new PBEKeySpec(sKey.toCharArray(), salt, 1024, 256); 
      SecretKey tmp = factory.generateSecret(spec); 
      SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
      //Encryption Process 
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, secret); 
      byte[] cipherText = cipher.doFinal(PlainMsg.getBytes()); 
      //return Base64Encoded(cipherText); 
      //Hex 
      return toHex(cipherText); 
     } 

解密

public String AESDecrypt(String sKey, String EncryptMsg) 
       throws Exception {   
      /*Old Method 
      //byte[] rawKey = getRawKey(sKey.getBytes("UTF-8")); 
      byte[] rawKey = getRawKey(sKey.getBytes()); 
      SecretKeySpec keySpec = new SecretKeySpec(rawKey, "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 
      cipher.init(Cipher.DECRYPT_MODE, keySpec); 
      //byte[] plainText = Base64Decoded(EncryptMsg.getBytes("UTF-8")); 
      byte[] plainText = Base64Decoded(EncryptMsg);   
      cipher.doFinal(plainText); 
      return new String(plainText, "UTF-8"); 
      */ 
      //New Method 
      byte[] salt = getSalt(); 
      SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC"); 
      KeySpec spec = new PBEKeySpec(sKey.toCharArray(), salt, 1024, 256); 
      SecretKey tmp = factory.generateSecret(spec); 
      SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); 
      //byte[] bCipherText = Base64Decoded(EncryptMsg); 
      //Hex 
      byte[] bCipherText = toByte(EncryptMsg); 
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, secret); 
      cipher.doFinal(bCipherText); 
      return new String(bCipherText); 
     } 

     private byte[] getSalt() throws NoSuchAlgorithmException { 
      /*Mark for old key method 
      //Initialize the KeyGenerator 
      KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
      SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
      sr.setSeed(seed); 
      //Init for 256bit AES key 
      kgen.init(Constants.AES_KEY_SIZE, sr);; 
      SecretKey secret = kgen.generateKey(); 
      //Get secret raw key 
      byte[] rawKey = secret.getEncoded(); 
      return rawKey; 
      */ 

      //New key method with some salt 
      SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 
      byte[] ransalt = new byte[20]; 
      random.nextBytes(ransalt); 
      return ransalt; 
     } 

     @Override 
     public byte[] getRawKey(byte[] seed) throws Exception { 
      /*Old Method 
      //Initialize the KeyGenerator 
      KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
      SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
      sr.setSeed(seed); 
      //Init for 256bit AES key 
      kgen.init(Constants.AES_KEY_SIZE, sr); 
      SecretKey secret = kgen.generateKey(); 
      //Get secret raw key 
      byte[] rawKey = secret.getEncoded(); 
      return rawKey; 
      */ 
      return null; 
     } 
/** 
* 
* @param toBeDecoded 
* @return 
*/ 
     public byte[] Base64Decoded(String toBeDecoded) { 
      byte[] decoded = Base64.decode(toBeDecoded, 0); 
      return decoded; 
     } 

     //Hex Mode 
     public String toHex(String txt) { 
      return toHex(txt.getBytes()); 
     } 
     public String fromHex(String hex) { 
      return new String(toByte(hex)); 
     } 

     public byte[] toByte(String hexString) { 
      int len = hexString.length()/2; 
      byte[] result = new byte[len]; 
      for (int i = 0; i < len; i++) 
       result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue(); 
      return result; 
     } 

     public String toHex(byte[] buf) { 
      if (buf == null) 
       return ""; 
      StringBuffer result = new StringBuffer(2*buf.length); 
      for (int i = 0; i < buf.length; i++) { 
       appendHex(result, buf[i]); 
      } 
      return result.toString(); 
     } 
     private final String HEX = "ABCDEF"; 
     private void appendHex(StringBuffer sb, byte b) { 
      sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f)); 
     } 


    } 

我引用/這些代碼#2相比: Android aes encryption pad block corruptedincorrect decryption using AES/CBC/PKCS5Padding in Android

似乎我的問題在於字符集編碼,但我無法找出問題所在。

任何意見/答覆非常感謝! 謝謝你幫助我!

+0

任何想法的傢伙? – dumbfingers

回答

0

我寫的代碼完美無瑕。看看下面這個鏈接:

http://pocket-for-android.1047292.n5.nabble.com/Encryption-method-and-reading-the-Dropbox-backup-td4344194.html#a4454327

沒有在你的代碼太仔細看我建議你應該在這裏指定編碼,雖然我不知道如果這是你的問題的原因:

byte[] cipherText = cipher.doFinal(PlainMsg.getBytes()); 

這裏:

return new String(bCipherText); 
+0

謝謝你,但我試過指定編碼方法,但仍然無法獲得正確的結果。然後我刪除了所有的代碼,並做了一個簡單的重寫,這次相同的代碼工作。仍然不知道我的代碼發生了什麼,也許這個加密不能通過定義一個「接口」類來實現? – dumbfingers