【问题标题】:Decrypting aes-256-cbc using bouncycastle使用 bouncycastle 解密 aes-256-cbc
【发布时间】:2015-08-22 05:02:05
【问题描述】:

bouncyCastle 新手,感谢您的帮助。我正在尝试使用 bouncycastle java API 在我的系统上解密由第三方加密的文件。除了解密文件开头的垃圾数据blob之外,它似乎可以很好地解密文件。下面的代码

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();
}

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

下面的用于解密文件的 openssl 命令可以正常工作。实际上我在解密时使用的是openssl打印出来的密钥和iv。

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

【问题讨论】:

标签: java encryption cryptography bouncycastle


【解决方案1】:

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

因为前一个块被用作 CBC 中下一个块的向量,所以 16 个字节的后续块也会受到影响,在开始时为您提供 32 个随机字节。相反,字节 16 到 31 应该与 IV 进行异或。

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

【讨论】:

  • 非常感谢,现在更有意义了。从您的指针最终从密码中导出密钥和 IV,并在密文上跳过 16 个字节以摆脱 blob。
  • 这就是票。请注意,BytesToKey 并不是最好的 PBKDF(基于密码的密钥派生函数)。它默认只使用一次迭代;如果可能,您应该切换到 PBKDF2 和/或高迭代次数。或者您当然可以使用非常强大的密码。
猜你喜欢
  • 2013-08-11
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 2017-09-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多