2012-05-05 53 views
1

我正在開發一個處理SMS的android應用程序。
我完成了應用程序,但最後一件事仍未解決:加密。解密時SMS加密給出異常

我該如何解決傳入短信的加密問題?

public class enc { 

     private String iv = "fedcba"; 
     private IvParameterSpec ivspec; 
     private SecretKeySpec keyspec; 
     private Cipher cipher; 

     private String SecretKey = "abcdef"; 

     public enc() 
     { 
      ivspec = new IvParameterSpec(iv.getBytes()); 

      keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES"); 

      try { 
       cipher = Cipher.getInstance("AES/CBC/NoPadding"); 
      } catch (NoSuchAlgorithmException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } catch (NoSuchPaddingException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     public String encrypt(String text) throws Exception 
     { 
      if(text == null || text.length() == 0) 
       throw new Exception("Empty string"); 

      byte[] encrypted = null; 

      try { 
       cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec); 

       encrypted = cipher.doFinal(padString(text).getBytes()); 
      } catch (Exception e) 
      {   
       throw new Exception("[encrypt] " + e.getMessage()); 
      } 
      String s = new String(encrypted); 
      Log.v("TAG", s); 


      return s; 
     } 

     public String decrypt(String code) throws Exception 
     { 
      if(code == null || code.length() == 0) 
       throw new Exception("Empty string"); 

      byte[] decrypted = null; 

      try { 
       cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec); 

       decrypted = cipher.doFinal(hexToBytes(code)); 
      } catch (Exception e) 
      { 
       throw new Exception("[decrypt] " + e.getMessage()); 
      } 
      Log.v("TAG", decrypted.toString()); 
      String s = new String(decrypted); 
      Log.v("TAG", s); 
      return s; 
     } 



     public static String bytesToHex(byte[] data) 
     { 
      if (data==null) 
      { 
       return null; 
      } 

      int len = data.length; 
      String str = ""; 
      for (int i=0; i<len; i++) { 
       if ((data[i]&0xFF)<16) 
        str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF); 
       else 
        str = str + java.lang.Integer.toHexString(data[i]&0xFF); 
      } 
      return str; 
     } 


     public static byte[] hexToBytes(String str) { 
      if (str==null) { 
       return null; 
      } else if (str.length() < 2) { 
       return null; 
      } else { 
       int len = str.length()/2; 
       byte[] buffer = new byte[len]; 
       for (int i=0; i<len; i++) { 
        buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16); 
       } 
       return buffer; 
      } 
     } 



     private static String padString(String source) 
     { 
      char paddingChar = ' '; 
      int size = 16; 
      int x = source.length() % size; 
      int padLength = size - x; 

      for (int i = 0; i < padLength; i++) 
      { 
       source += paddingChar; 
      } 

      return source; 
     } 
    } 

我試過這個,但是解密時它給出了一個例外,它不能解析「A字符」。
通過一個字符,我的意思是一個像a,b,c這樣的字母表,不能被解析。

任何幫助?

04-24 13:56:17.191: V/(2031): Message Recieved 
04-24 13:56:22.811: V/TAG(2031): [[email protected] 
04-24 13:56:22.811: V/Encrypted(2031): [[email protected] 
04-24 13:56:22.931: W/System.err(2031): java.lang.Exception: [decrypt] unable to parse '[B' as integer 
04-24 13:56:22.941: W/System.err(2031):  at sms.app.enc.decrypt(enc.java:86) 
04-24 13:56:22.951: W/System.err(2031):  at sms.app.SMSReceiver.onReceive(SMSReceiver.java:86) 
04-24 13:56:22.961: W/System.err(2031):  at android.app.ActivityThread.handleReceiver(ActivityThread.java:2810) 
04-24 13:56:22.961: W/System.err(2031):  at android.app.ActivityThread.access$3200(ActivityThread.java:125) 
04-24 13:56:22.970: W/System.err(2031):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2083) 
04-24 13:56:22.981: W/System.err(2031):  at android.os.Handler.dispatchMessage(Handler.java:99) 
04-24 13:56:22.981: W/System.err(2031):  at android.os.Looper.loop(Looper.java:123) 
04-24 13:56:22.991: W/System.err(2031):  at android.app.ActivityThread.main(ActivityThread.java:4627) 
04-24 13:56:23.001: W/System.err(2031):  at java.lang.reflect.Method.invokeNative(Native Method) 
04-24 13:56:23.001: W/System.err(2031):  at java.lang.reflect.Method.invoke(Method.java:521) 
04-24 13:56:23.011: W/System.err(2031):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868) 
04-24 13:56:23.021: W/System.err(2031):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626) 
04-24 13:56:23.021: W/System.err(2031):  at dalvik.system.NativeStart.main(Native Method) 
+0

看起來您需要更好地理解Java字符和字節之間的差異,因爲您的代碼顯示出根本性的誤解。它沒有任何意義,並且可能無法從加密輸出中構造字符串。另外,使用'toString()'對於byte []'數組沒有意義。 –

+1

@GregS如果我甚至不使用toString方法並使用字節數組itt仍然給出相同的異常 – kashifmehmood

+0

我明白,但我的觀點是,您需要更熟悉字符和字節之間的差異。 –

回答

0

您可能想要發佈完整的堆棧跟蹤。如果您的代碼存在三個問題:

  • 您的密鑰很脆弱:您應該只從某些ASCII字符構造密鑰。這嚴重限制了密鑰空間,並且使得密鑰的蠻力變得容易。不使用非標準填充的密鑰不可用。使用Cipher.getInstance("AES/CBC/PKCS5Padding")得到適當的填充
  • 不使用固定的IV,產生一個隨機對每個加密操作

此外,使用getBytes()可能給奇怪的結果,因爲編碼是不確定的(使用平臺默認) 。它可能會在Android上一致,但使用getBytes("UTF-8")來確保您從相同的字符串中獲得相同的字節。

+0

用logcat修改請檢查出 – kashifmehmood

+0

檢查你的輸入和輸出。您的加密代碼似乎試圖將加密(〜隨機字節)轉換爲一個字符串,而解密代碼似乎期望一個十六進制編碼的字符串。 (主要是@GregS說的) –