以下 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 的正确选项组合。
首先,
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.