简体   繁体   English

AES加密使用openssl解密使用java

[英]AES encrypt with openssl decrypt using java

I have to encrypt an xml file using openssl command line or a C api.我必须使用 openssl 命令行或 C api 加密一个 xml 文件。 The output shall be Base64.输出应为 Base64。

A java programm will be used for decrypting. java程序将用于解密。 This programm is provided by the customer and cannot be changed (they are using this code for legacy applications).此程序由客户提供且无法更改(他们将此代码用于遗留应用程序)。 As you can see in the code below the customer provides a passphrase so the key will be generated using the SecretKeySpec method.正如您在下面的代码中看到的那样,客户提供了一个密码短语,因此将使用 SecretKeySpec 方法生成密钥。

Java code:爪哇代码:

// Passphrase
private static final byte[] pass = new byte[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0','1', '2', '3', '4', '5' };


public static String encrypt(String Data) throws Exception {
    Key key = generateKey();
    Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
    c.init(Cipher.ENCRYPT_MODE, key);
    byte[] encVal = c.doFinal(Data.getBytes());
    String encryptedValue = new BASE64Encoder().encode(encVal);
    return encryptedValue;
}

public static String decrypt(String encryptedData) throws Exception {
    Key key = generateKey();
    Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
    c.init(Cipher.DECRYPT_MODE, key);
    byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
    byte[] decValue = c.doFinal(decordedValue);
    String decryptedValue = new String(decValue);
    return decryptedValue;
}

private static Key generateKey() throws Exception {
    Key key = new SecretKeySpec(pass, "AES");
    return key;
}

I have tested several commands like:我已经测试了几个命令,例如:

    openssl enc -aes-128-ecb -a -salt -in file.xml -out file_enc.xml -pass pass:123456789012345
    openssl enc -aes-128-ecb -a -nosalt -in file.xml -out file_enc.xml -pass pass:123456789012345

But non of the given outputs is successfuly decrypted using java.但是给定的输出中没有一个是使用 java 成功解密的。 For testing purposes I used the given java code for encrypting and the result is of course different than the one from openssl.出于测试目的,我使用给定的 java 代码进行加密,结果当然与来自 openssl 的结果不同。

Is there a way to use openssl C api or command line to encrypt data so it could be successful decrypted using the given java code?有没有办法使用openssl C api或命令行来加密数据,以便使用给定的java代码成功解密?

Java's SecretKeySpec uses the password ASCII bytes directly as key bytes, while OpenSSL's -pass pass:... method derives a key from the password using a key derivation function to transform the password into a key in a secure fashion. Java的SecretKeySpec使用密码ASCII直接字节密钥字节,而OpenSSL的-pass pass:...方法得出使用从密码键密钥导出函数,以密码转变成以安全的方式的关键。 You can either try to do the same key derivation in Java (which you probably cannot if I interpret your question correctly), or use OpenSSL's -K option to pass in a key (as hex bytes!) instead of a password.您可以尝试在 Java 中进行相同的密钥派生(如果我正确解释您的问题,您可能无法这样做),或者使用 OpenSSL 的-K选项传递密钥(作为十六进制字节!)而不是密码。

You can find out how there .你可以在那里找到方法。

To add a bit.要补充一点。 I was struggling with the same problem.我正在努力解决同样的问题。 I was able to decrypt from Java an AES-128 encrypted message using the following settings.我能够使用以下设置从 Java 解密 AES-128 加密消息。

I used openssl to encrypt the data:我使用openssl来加密数据:

openssl enc -nosalt -aes-128-ecb -in data.txt -out crypted-aes.data -K 50645367566B59703373367639792442

As @Daniel suggested, the game changer is to use the -K property.正如@Daniel 所建议的那样,改变游戏规则的是使用-K属性。 The Java configuration that let us to decrypt the generated file is the following:让我们解密生成文件的Java配置如下:

final byte[] aesKey = "PdSgVkYp3s6v9y$B".getBytes(StandardCharsets.UTF_8);
final SecretKeySpec aesKeySpec = new SecretKeySpec(aesKey, "AES");
Path path = Paths.get("src/test/resources/crypted-aes.data");
final byte[] cryptedData = Files.readAllBytes(path);
final Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, aesKeySpec);
final byte[] decryptedMsg = cipher.doFinal(cryptedData);

The magic happens when the hex key 50645367566B59703373367639792442 , its String representation "PdSgVkYp3s6v9y$B" , and the AES/ECB/PKCS5Padding align together.当十六进制密钥50645367566B59703373367639792442 、它的String表示"PdSgVkYp3s6v9y$B"AES/ECB/PKCS5Padding对齐时,魔法就会发生。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM