java - 使用 bouncycaSTLe 解密 aes-256-cbc

标签 java encryption cryptography bouncycastle

刚接触 bouncyCaSTLe,非常感谢任何帮助。我正在尝试使用 bounncycaSTLe java API 在我的系统上解密由第三方加密的文件。除了解密文件开头的垃圾数据之外,它似乎可以很好地解密文件。下面的代码

PaddedBufferedBlockCipher aes = new PaddedBufferedBlockCipher(new CBCBlockCipher(
                    new AESEngine()));
            CipherParameters ivAndKey = new ParametersWithIV(new KeyParameter(DatatypeConverter.parseHexBinary(keyInfo.getKey())),
                    DatatypeConverter.parseHexBinary(keyInfo.getInitializationVector()));
            aes.init(false, ivAndKey);

            byte[] decryptedBytes = cipherData(aes, Base64.decodeBase64(inputStreamToByteArray(new FileInputStream(encryptedFile))));

            return new ByteArrayInputStream(decryptedBytes);

private static byte[] cipherData(PaddedBufferedBlockCipher cipher, byte[] data)
        throws Exception {
    int minSize = cipher.getOutputSize(data.length);
    byte[] outBuf = new byte[minSize];
    int length1 = cipher.processBytes(data, 0, data.length, outBuf, 0);
    int length2 = cipher.doFinal(outBuf, length1);
    int actualLength = length1 + length2;
    byte[] result = new byte[actualLength];
    System.arraycopy(outBuf, 0, result, 0, result.length);
    return result;
}
private byte[] inputStreamToByteArray(InputStream is) throws IOException {

    ByteArrayOutputStream buffer = new ByteArrayOutputStream();

    int numberRead;
    byte[] data = new byte[16384];

    while ((numberRead = is.read(data, 0, data.length)) != -1) {
        buffer.write(data, 0, numberRead);
    }

    buffer.flush();

    return buffer.toByteArray();
}

解密的数据 block 看起来很好,除了开头 “???&??ovKw??????C??:?8?06??85042| | “

用于解密文件的 openssl 命令在下面的命令中运行良好。事实上我在解密时使用的是 openssl 打印出来的 key 和 iv。

openssl aes-256-cbc -d -salt -in cryptofile.txt -pass pass:password -a -p

最佳答案

解决方案很简单:跳过密文 blob 的前 16 个字节。加密的 blob 以魔法开头(您可以尝试将前 8 个字节读取为 ASCII 文本),然后是 8 个字节的随机盐,它们与密码一起使用来派生 key 和 IV(使用 OpenSSL 专有密码哈希机制)称为 EVP_BytesToKey )。

由于前一个 block 用作 CBC 中下一个 block 的 vector ,因此 16 字节的后续 block 也会受到影响,从而在开始时为您提供 32 个随机字节。相反,字节 16 到 31 应该与 IV 进行异或运算。

这是a Java implementation of BytesToKey使用我的旧昵称发布。

关于java - 使用 bouncycaSTLe 解密 aes-256-cbc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30697121/

相关文章:

Java Jersey 2 实现过滤器

c# - Entity Framework 和加密数据库

java - 使用 keytool 生成 128 位 key

C# AES 加密字节数组

javascript - Tomcat WebSocket 中的 "Failed to decompress a compressed WebSocket frame"错误

java - Log4j2 - 为什么我的 "Logger"元素隐藏了 "Root"记录器的内容?

java - 使用Maven for Java程序在hdfs上写入时的Hadoop错误

encryption - MD5 生成如何取决于文件大小?

java - JAVA上使用RSA加密解密的问题

go - 如何解压缩 Go 中 ECDH P256 曲线上的单个 X9.62 压缩点?