【问题标题】:Unable to decrypt csv file using symmetric key java无法使用对称密钥java解密csv文件
【发布时间】:2018-06-15 12:31:22
【问题描述】:

为我提供了两个文件 encrypted_key.encencrypted_data.csv.enc。我需要使用我的私钥解密 encrypted_key.enc 以获得对称密钥,然后使用该对称密钥解密 encrypted_data.csv.enc 文件。 p>

在终端上,以下命令完成工作:

openssl rsautl -decrypt -ssl -inkey my_private_key -in encrypted_key.enc -out key

openssl aes-256-cbc -d -in encrypted_data.csv.enc -out secret.txt -pass file:key

我的目标是执行这两个命令的 java 等效项。我能够成功解密第一个文件并检索对称密钥。

现在我无法使用该对称密钥来解密 csv 文件。我的问题出现在decipher.init(Cipher.DECRYPT_MODE, keySpec); 我收到以下堆栈跟踪

线程“main”java.security.InvalidKeyException 中的异常:非法密钥大小或默认参数

我不清楚我在解密过程中究竟遗漏了什么。我试过更改密码提供程序,但这没有帮助。其他帖子使用IVParameterSpec 发布了解决方案,但我的解密案例似乎不需要它,或者我不知道该放在哪里。

    File file = new File("my_private_key");
    PrivateKey pk = getPrivateKey(file);

    // Decrypt secret key
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, pk);
    File skFile = new File("encrypted_key.enc");
    FileInputStream fileInputStream = new FileInputStream(skFile);
    byte[] decodedBytes = IOUtils.toByteArray(fileInputStream);
    byte[] original = cipher.doFinal(decodedBytes);
    String decodedOriginal = new String(Base64.encodeBase64(original));
    System.out.println(decodedOriginal);

    // Use the secret key for decrypting file
    File csvFile =
            new File(
                    "encrypted_data.csv.enc");
    FileInputStream csvIS = new FileInputStream(csvFile);
    Cipher decipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
    SecretKeySpec keySpec = new SecretKeySpec(original, "AES");

    decipher.init(Cipher.DECRYPT_MODE, keySpec);

    byte[] csvOriginal = decipher.doFinal(IOUtils.toByteArray(csvIS));
    String csvContents = new String(csvOriginal);
    System.out.println(csvContents);

【问题讨论】:

    标签: java encryption


    【解决方案1】:

    在 Java 1.8 之前(我认为,在附近的某个地方),对于 128 位以上的密钥大小,您会受到 Java Unlimited Strength Policy 的限制。这是您遇到异常的最可能原因。

    很遗憾,这不会修复您的代码。带有pass 标志的openssl 使用名为EVP_BytesToKey() 的不安全KDF。 Java 本身并不支持此 KDF。无论如何,您都不想使用它,因为它不安全。更新上游代码以使用更好的 KDF,例如 PBKDF2。 Java 对此有本机支持。

    此外,您在 openssl 中使用 CBC 模式,在 Java 中使用 ECB 模式。而且您没有在 openssl 中指定 IV。我的印象是您没有自己编写 Java 代码。花时间学习和研究代码和正在执行的命令中实际发生的情况可能会让您受益,并且您可能更有能力解决问题。

    【讨论】:

    • Oracle/Sun 8u161 或 9 以下的 Java(但不是 OpenJDK)有限制到 128 位的问题,尽管 8u151/2 有部分解决方案(文本编辑 @987654325 @ 而不是下载 jars)。 openssl enc 在 PBE 模式下使用 EVP_BytesToKey 在需要时派生密钥和 IV(用于 CBC)。如果您使用 RSA 传输良好的随机密钥(不是密码),则不需要任何 PBKDF(如果正确的大小甚至不需要 KBKDF)。
    • @dave_thompson_085 感谢您的清理。我同意,直接传输密钥可能是首选。您可以使用 -K 标志指定十六进制密钥到 openssl enc 我相信。
    • @LukeJoshuaPark 你说得对,我从 StackOverflow 和其他来源获得的任何帮助拼凑出这段 Java 代码。关于openssl代码sn-p,解密文件更安全的bash命令是什么?此外,即使在 Java 的 CBC 模式下,我也需要在 openssl 中指定 IV,但我不清楚我将在哪里获得该值。
    • @user2548635 问题不在于 decrypt 文件的安全方式,而在于 encrypt 文件中的安全方式第一名。问题真的归结为 OpenSSL 使用的 KDF:它简直太糟糕了。您应该调整文件最初的加密方式,以便可以使用带有-K-iv 标志的openssl enc 对其进行解密。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 1970-01-01
    • 1970-01-01
    • 2021-08-27
    • 2011-08-30
    相关资源
    最近更新 更多