2013-01-17 2 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

예, 안드로이드 암호가 몇 가지 문제를 가지고있다. 하나는 cipher.doFinal (암호화 된)의 byte []가 올바른 길이를 가져야 할 때가 있다는 것입니다. 이 예는 마지막으로 작동 많은 고통스러운 시간 후 128 비트 (? 공의와 입력)

의 암호화 된 배열을 공급하십시오 :

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()의 특정 가져 오기는 무엇입니까? –

관련 문제