使用openssl解密Java生成的AES文件

问题描述 投票:0回答:1

以下 Java 生成加密数据:

  private static final int KEY_LENGTH = 256;
  private static final int ITERATION_COUNT = 65536;

  public static String encrypt(String strToEncrypt, String secretKey, String salt) {

    try {

        SecureRandom secureRandom = new SecureRandom();
        byte[] iv = new byte[16];
        secureRandom.nextBytes(iv);
        IvParameterSpec ivspec = new IvParameterSpec(iv);

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
        KeySpec spec = new PBEKeySpec(secretKey.toCharArray(), salt.getBytes(), ITERATION_COUNT, KEY_LENGTH);
        SecretKey tmp = factory.generateSecret(spec);
        SecretKeySpec secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivspec);

        byte[] cipherText = cipher.doFinal(strToEncrypt.getBytes("UTF-8"));
        byte[] encryptedData = new byte[iv.length + cipherText.length];
        System.arraycopy(iv, 0, encryptedData, 0, iv.length);
        System.arraycopy(cipherText, 0, encryptedData, iv.length, cipherText.length);

        return Base64.getEncoder().encodeToString(encryptedData);
    } catch (Exception e) {
        // Handle the exception properly
        e.printStackTrace();
        return null;
    }
  }

运行如下:

encrypt( "Hello, this is a secret message.", "MySecretKey", "MySalt");

给出结果:

zYsUELxuE3KT4IDa1cbRnX70OSlQTbcDa1LEuh0IzfjZZcJhnuX8kLFcGqYLWjfp0XJzfgwFreZIqmqE1HqlGw==

我将其保存到文件中,现在想使用 openssl 来解密它。

我在 openssl 中使用了多种选项,但我似乎无法让它工作,例如:

 echo -n MySalt | od -A n -t x1 | perl -lpe's,\s+,,g'
4d7953616c74

openssl enc -e -aes-256-cbc -k MySecretKey -S 4d7953616c74  -md sha256 -in file.in
hex string is too short, padding with zero bytes to length
*** WARNING : deprecated key derivation used.
Using -iter or -pbkdf2 would be better.

openssl enc -e -aes-256-cbc -k MySecretKey -S 4d7953616c74 -iter 65536 -md sha256 -in file.in
hex string is too short, padding with zero bytes to length
z....garbage..........

我找不到 openssl 的正确选项组合。

java openssl javax.crypto
1个回答
0
投票

首先,

enc -e
(或默认)是加密的;
-d
是解密。另外,
enc
期望(并放置)盐在文件的开头,但不期望(或放置)IV,并且默认情况下不执行PBKDF2。并且只有 3.2.0 以上(即最近几个月发布的)可以使用传统 8 以外的盐长度。

所以如果你有 3.2.0 以上版本:

$ echo zYsUELxuE3KT4IDa1cbRnX70OSlQTbcDa1LEuh0IzfjZZcJhnuX8kLFcGqYLWjfp0XJzfgwFreZIqmqE1HqlGw== | \
> openssl base64 -d -A >78319330.bin
$ iv=$( dd if=78319330.bin bs=16 count=1 status=none | xxd -p ) # or if no xxd, something like your od+sed
$ ( printf Salted__MySalt; dd if=78319330.bin bs=16 skip=1 status=none ) | \
> openssl enc -d -aes-256-cbc -k MySecretKey -pbkdf2 -iter 65536 -saltlen 6 -iv $iv
Hello, this is a secret message.
© www.soinside.com 2019 - 2024. All rights reserved.