【问题标题】:Decrypting OpenSSL-encrypted file on Android with Java使用 Java 在 Android 上解密 OpenSSL 加密的文件
【发布时间】:2016-05-04 17:23:11
【问题描述】:

我目前正在尝试在我的 Android 应用上实现文件解密。

文件将在主机(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

问题在于,我无法在 Android 上正确解密这些组合(128/256、ecb/cbc、salt/nosalt、-K/-k、-md/none)。

它要么解密完全错误(损坏),要么抛出异常。

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、salt/nosalt、ecb/cbc),因为如果它被破解,不会发生任何严重的事情。

谁能建议我如何调整代码 还是带有新的 openssl 命令组合的新代码?

TL;DR - 我需要一个可以解密在 Linux 上通过 openssl 命令加密的文件的 Android Java 代码。

【问题讨论】:

    标签: java android encryption openssl cryptography


    【解决方案1】:

    如果我使用 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
    

    【讨论】:

      猜你喜欢
      • 2016-09-25
      • 1970-01-01
      • 2012-04-07
      • 2021-02-02
      • 2020-01-20
      • 2013-01-07
      • 2015-02-18
      • 2012-07-31
      相关资源
      最近更新 更多