在Android上解密用OpenSSL enc子命令加密的文件

3

我在服务器上使用OpenSSL命令加密了一个文件:

openssl enc -aes-256-ecb -salt -in ori.pdf -out encrypted.pdf -pass pass:testpassword -p

以下是加密完成后显示的密钥和盐:
salt=BE1EFCBAE984CB24
key=50B62ECEF1B777353372A44CDDC463987815F783E39D68B8EE6A0AB74A79C7FA

我曾尝试使用以下解密方式对其进行解密:

String key  = "50B62ECEF1B777353372A44CDDC463987815F783E39D68B8EE6A0AB74A79C7FA";
byte[] keyBytes = key.getBytes("UTF-8");
SecretKey keySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
buffer = cipher.doFinal(buffer);

如何在Android中解密加密文件?

永远不要使用ECB模式。它是确定性的,因此不具备语义安全性。你至少应该使用像CBCCTR这样的随机化模式。最好对你的密文进行身份验证,以防止像填充预言攻击这样的攻击。可以使用GCM或EAX这样的认证模式,或者使用先加密后进行消息认证码的方案来实现。 - Artjom B.
我相信OpenSSL的enc子命令使用EVP_BytesToKey,它可能是一个非标准混合函数。这就是子命令获取密钥和iv的地方。你可能需要复制它。我知道其他库,比如Crypto++,为互操作性提供了该功能。我认为这可能是你可以用来找到答案的问题:如何在Java中使用openssl解密加密文件,使用AES? - jww
非常感谢@jww的建议,帮助我解决了我的问题。 - MinFu
1个回答

0

我在原回答中犯了错误。我误读了字符串为“base 64”。实际上,它只是“十六进制编码”。

修改此语句:

byte[] keyBytes = key.getBytes("UTF-8");

变成这样:

byte [] keyBytes = hexStringToByteArray(key);

其中 hexStringToByteArray 是从这里的答案中提取的函数 (链接)

public static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接