2016-01-27 86 views
2

我目前正試圖在Android應用上實現文件解密。使用Java解密Android上的OpenSSL加密文件

該文件將在主機上使用類似的加密(Linux)的:

openssl aes-128-ecb -salt -k $HASH -in somefile.in -out somefile 
openssl aes-256-cbc -salt -K $HASH -iv $IV -md sha1 -in somefile.in -out somefile 
openssl aes-256-cbc -d -salt -K $HASH -md sha1 -in somefile.in -out somefile 

的是,我不能讓任何這些組合(128/256,ECB/CBC,鹽/ nosalt的問題, -K/-k,-md/none)在Android上正確解密。

它要麼解密完全錯誤(損壞),要麼引發異常。

Exception at decryptAES 
java.io.IOException: Error while finalizing cipher 
    at javax.crypto.CipherInputStream.fillBuffer(CipherInputStream.java:104) 
    at javax.crypto.CipherInputStream.read(CipherInputStream.java:155) 
    at java.io.InputStream.read(InputStream.java:162) 
    at com.temp.temp.CryptographyHelper.decryptAES(CryptographyHelper.java:58) 
    at com.temp.temp.MainActivity.__prepFirstLaunch(MainActivity.java:229) 
    at com.temp.temp.MainActivity.prepFirstLaunch(MainActivity.java:192) 
    at com.temp.temp.MainActivity$prepthread.run(MainActivity.java:42) 
Caused by: javax.crypto.BadPaddingException: EVP_CipherFinal_ex 
    at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method) 
    at com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430) 
    at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:490) 
    at javax.crypto.Cipher.doFinal(Cipher.java:1314) 
    at javax.crypto.CipherInputStream.fillBuffer(CipherInputStream.java:102) 
    ... 6 more 

下面是我的Android應用程序中的當前Java代碼(不工作)。

public static InputStream decryptAES(Context context) { 
    InputStream ris = null; 

    try { 
     InputStream fis = context.getAssets().open("somefile"); 
     FileOutputStream baos = new FileOutputStream("/sdcard/decrypted"); 
     String hash = "SOMEHASH"; 
     String ivs = "SOMEIV"; 

     IvParameterSpec iv = new IvParameterSpec(ivs.getBytes("UTF-8")); 
     SecretKeySpec sks = new SecretKeySpec(hash.getBytes("UTF-8"), "AES"); 

     // None of these work 
     Cipher cipher = Cipher.getInstance("AES"); 
     //Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
     //Cipher cipher = Cipher.getInstance("AES/ECB/ZeroBytePadding"); 
     //Cipher cipher = Cipher.getInstance("AES/CBC/ZeroBytePadding"); 
     //Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, sks); 
     //cipher.init(Cipher.DECRYPT_MODE, sks, iv); 
     CipherInputStream cis = new CipherInputStream(fis, cipher); 
     int b; 
     byte[] d = new byte[1024 * 32]; 
     while ((b = cis.read(d)) != -1) { 
      baos.write(d, 0, b); 
     } 
     baos.flush(); 
     baos.close(); 
     cis.close(); 
    } catch (Exception e) { 
     // Meh 
    } 

    return ris; 
} 

我不在乎我結束了,就好像它被盜取沒有發生關鍵哪種加密方法(128/256,鹽/ nosalt,ECB/CBC)。

任何人都可以建議我如何調整代碼 或新的代碼與新的openssl命令組合?

TL; DR - 我需要一個Android Java代碼,可以解密通過openssl命令在Linux上加密的文件。

回答

2

如果我加密這樣使用OpenSSL文件:

> echo "Some test" > test.txt 
> openssl aes-128-cbc -K "000102030405060708090A0B0C0D0E0F" -iv "77665544332211000011223344556677" -in test.txt -out test.enc 

我可以解密這樣在Java:

public static void main(String[] args) { 
    try { 
     byte[] keyBytes = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}; 
     byte[] ivBytes = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77}; 

     SecretKeySpec sks = new SecretKeySpec(keyBytes, "AES"); 
     IvParameterSpec iv = new IvParameterSpec(ivBytes); 

     Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
     cipher.init(Cipher.DECRYPT_MODE, sks, iv); 

     // read file to byte[] 
     InputStream is = new FileInputStream("test.enc"); 
     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
     int b; 
     while ((b = is.read()) != -1) { 
      baos.write(b); 
     } 
     byte[] fileBytes = baos.toByteArray(); 

     byte[] decrypted = cipher.doFinal(fileBytes); 
     System.out.println(new String(decrypted)); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
} 

結果:

Some test