2013-01-17 106 views
2

我需要加密一個字符串,然後解密。加密函數運行良好,但是當我傳遞加密值解密函數時,我收到一個空指針異常。如果我在Java應用程序中使用相同的代碼,那麼運行良好。Android - Crittografy密碼解密不起作用

public class Cripthografy { 
private static String TAG="freeliberomail"; 

public static String encrypt(String seed, String cleartext){ 
    byte[] rawKey; 
    byte[] result=null; 
try { 
rawKey = getRawKey(seed.getBytes()); 

    result = encrypt(rawKey, cleartext.getBytes()); 
    } catch (Exception e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } 
    return toHex(result); 
    } 

    public static String decrypt(String seed, String encrypted) { 
    byte[] rawKey; 
    byte[] result=null; 
    try { 
rawKey = getRawKey(seed.getBytes()); 

    byte[] enc = toByte(encrypted); 
    result = decrypt(rawKey, enc); 
    } catch (Exception e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } 
    return new String(result); 
    } 


    private static byte[] getRawKey(byte[] seed) throws Exception { 
     KeyGenerator kgen = KeyGenerator.getInstance("AES"); 
     SecureRandom sr = SecureRandom.getInstance("SHA1PRNG"); 
     sr.setSeed(seed); 
     kgen.init(128, sr); // 192 and 256 bits may not be available 
     SecretKey skey = kgen.generateKey(); 
     byte[] raw = skey.getEncoded(); 
     return raw; 
    } 
    private static byte[] encrypt(byte[] raw, byte[] clear){ 
byte[] encrypted=null; 
     SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
     Cipher cipher; 
    try { 
cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec); 
    encrypted = cipher.doFinal(clear); 
    } catch (NoSuchAlgorithmException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } catch (NoSuchPaddingException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } catch (InvalidKeyException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } catch (BadPaddingException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } 
    return encrypted; 
    } 


    private static byte[] decrypt(byte[] raw, byte[] encrypted) { 
byte[] decrypted = null; 
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES"); 
    Cipher cipher; 
    try { 
cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.DECRYPT_MODE, skeySpec); 
    decrypted = cipher.doFinal(encrypted); 
    }catch (NoSuchAlgorithmException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } catch (NoSuchPaddingException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
     } catch (InvalidKeyException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } catch (IllegalBlockSizeException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } catch (BadPaddingException e) { 
// TODO Auto-generated catch block 
e.printStackTrace(); 
    } 

    return decrypted; 
    } 


    public static String toHex(String txt) { 
    return toHex(txt.getBytes()); 
    } 

public static String fromHex(String hex) { 
return new String(toByte(hex)); 
} 

public static 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 static 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 static String HEX = "ABCDEF"; 
    private static void appendHex(StringBuffer sb, byte b) { 
    sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f)); 
    } 

} 

然後我打電話:

  String encValue=Cripthografy.encrypt("MY_KEY", "helloworld"); 
     String decValue=Cripthografy.decrypt("MY_KEY", encValue); 
     Log.d(TAG,"encript:"+encValue+" "+"decript:"+decValue); 

的例外是:

 01-17 03:57:23.986: W/System.err(29846): javax.crypto.BadPaddingException: pad  block corrupted 
     01-17 03:57:23.991: W/System.err(29846):  at  com.android.org.bouncycastle.jcajce.provider.symmetric.util.BaseBlockCipher.engineDoFinal(B   aseBlockCipher.java:709) 
     01-17 03:57:23.991: W/System.err(29846):  at  javax.crypto.Cipher.doFinal(Cipher.java:1111) 
     01-17 03:57:23.991: W/System.err(29846): at marvellous.freeliberomail.Cripthografy.decrypt(Cripthografy.java:111) 
     01-17 03:57:23.991: W/System.err(29846): at marvellous.freeliberomail.Cripthografy.decrypt(Cripthografy.java:55) 
     01-17 03:57:23.991: W/System.err(29846): at marvellous.freeliberomail.Auth.writeCookieTofile(Auth.java:307) 
     01-17 03:57:23.991: W/System.err(29846): at marvellous.freeliberomail.Auth.createSessionCookie(Auth.java:287) 
     01-17 03:57:23.991: W/System.err(29846): at marvellous.freeliberomail.Auth.scenario(Auth.java:196) 
     01-17 03:57:23.991: W/System.err(29846): at marvellous.freeliberomail.Auth.accessMail(Auth.java:117) 
     01-17 03:57:23.991: W/System.err(29846): at marvellous.freeliberomail.Auth.run(Auth.java:96) 
     01-17 03:57:23.991: W/System.err(29846):  at java.lang.Thread.run(Thread.java:856) 
     01-17 03:57:23.996: W/dalvikvm(29846): threadid=11: thread exiting with uncaught exception (group=0x41584930) 
      01-17 03:57:23.996: E/AndroidRuntime(29846): FATAL EXCEPTION: Thread-32785 
      01-17 03:57:23.996: E/AndroidRuntime(29846): java.lang.NullPointerException 
      01-17 03:57:23.996: E/AndroidRuntime(29846): at java.lang.String.<init>(String.java:141) 
      01-17 03:57:23.996: E/AndroidRuntime(29846): at marvellous.freeliberomail.Cripthografy.decrypt(Cripthografy.java:60) 
      01-17 03:57:23.996: E/AndroidRuntime(29846): at marvellous.freeliberomail.Auth.writeCookieTofile(Auth.java:307) 
      01-17 03:57:23.996: E/AndroidRuntime(29846): at marvellous.freeliberomail.Auth.createSessionCookie(Auth.java:287) 
      01-17 03:57:23.996: E/AndroidRuntime(29846): at marvellous.freeliberomail.Auth.scenario(Auth.java:196) 
      01-17 03:57:23.996: E/AndroidRuntime(29846): at marvellous.freeliberomail.Auth.accessMail(Auth.java:117) 
      01-17 03:57:23.996: E/AndroidRuntime(29846): at marvellous.freeliberomail.Auth.run(Auth.java:96) 
      01-17 03:57:23.996: E/AndroidRuntime(29846): at java.lang.Thread.run(Thread.java:856) 

回答

2

是,Android的密碼確實有一些問題。 一個是cipher.doFinal中的byte [](加密)有時必須具有正確的長度。試着用128位(用0填補?)

的加密陣列餵養它的許多痛苦小時後這個例子中最後的作品:

private static byte[] key = "12345678".getBytes();// 64 bit 
private static byte[] iv = "12345678".getBytes(); 

public static String encrypt(String in) { 
    String cypert = in; 
    try { 
     IvParameterSpec ivSpec = new IvParameterSpec(iv); 
     SecretKeySpec k = new SecretKeySpec(key, "DES"); 
     Cipher c = Cipher.getInstance("DES/CBC/PKCS7Padding"); 
     c.init(Cipher.ENCRYPT_MODE, k, ivSpec); 
     byte[] encryptedData = c.doFinal(in.getBytes()); 
     cypert = Base64.encodeLines(encryptedData); 
    } catch (Exception e) { 
     Debugger.error(e); 
    } 
    return cypert; 
} 


public static String decrypt(String in) throws Exception { 
    String plain=in; 
    try { 
     IvParameterSpec ivSpec = new IvParameterSpec(iv); 
     SecretKeySpec keys = new SecretKeySpec(key, "DES"); 
     Cipher cipher = Cipher.getInstance("DES/CBC/PKCS7Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, keys, ivSpec); 
     // decryption pass 
     byte[] cipherText = Base64.decodeLines(in); 
     int ctLength = cipherText.length; 
     byte[] plainText = new byte[cipher.getOutputSize(ctLength)]; 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     bos.write(cipher.doFinal(cipherText)); 
     plainText = bos.toByteArray(); 
     bos.close(); 
     plain = new String(plainText, "UTF8"); 
    } catch (Exception e) { 
     Debugger.error(e); 
    } 
    return plain; 
} 
+0

感謝的人,它的作品!它接受的密鑰長度超過8個字節嗎? –

+0

上次我嘗試了更長的鍵沒有奏效。看起來關鍵必須是具體的形式。讓我們繼續挖掘...... – Anno2001

+0

謝謝你......你能告訴我哪個是Base64.encodeline()的特定導入嗎? –