Java Openssl:无法解密长消息

时间:2018-08-24 16:42:49

标签: java encryption openssl aes

我正在使用Java加密文本,并尝试在Linux上使用Openssl对其解密。我正在CBC上使用AES-128。

当我使用Openssl解密Java生成的64个字符加密的字符串时,我收到来自Openssl的“错误解密”错误。但是,如果字符串是16个字符,则Openssl可以正确解密它。

我正在Linux上运行它:

echo ${encryptedText} | ./openssl aes-128-cbc -d -a -K $( echo -n ${KEY} | hexdump -v -e '/1 "%02X"') -iv $(echo -n ${IV} | hexdump -v -e '/1 "%02X"')

注意:$ encryptedText,$ KEY,$ IV作为字符串而不是十六进制传递。此命令将其转换为十六进制: $(echo -n $ {KEY} | hexdump -v -e'/ 1“%02X”')

并收到此错误:

358048944:error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length:evp_enc.c:460:

我来自Java的加密代码基本上是:

import javax.crypto.*;

Cipher cipher;
SecretKey key;
String IV;
IvParameterSpec params;

cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
String randomString = GENERATE_RANDOM_TYPEABLE_ASCII(16_LENGTH);

key = new SecretKeySpec(randomString.getBytes("UTF-8"), "AES");
IV = GENERATE_RANDOM_TYPEABLE_ASCII(16_LENGTH);
params = new IvParameterSpec(IV.getBytes("UTF-8"));

cipher.init(Cipher.ENCRYPT_MODE, key, params);
byte[] encryptedTextBytes = cipher.doFinal((decryptedString).getBytes("UTF-8")); // decryptedString is passed as a parameter

String encryptedText = new Base64().encodeAsString(encryptedTextBytes);
return encryptedText;

我不明白的是为什么我的密码只能用于16个字符串,但不能用于64个字符串。

要注意的另一件重要事情是,如果我使用http://aes.online-domain-tools.com/之类的在线工具解密文本,则字符串可以完美解密。因此,我认为我的加密工作正常,但由于某种原因,OpenSSL出现了问题。

1 个答案:

答案 0 :(得分:1)

我没有重现您的问题,但怀疑这是导致您遇到问题的原因:Base64.encodeAsString()函数在使用时会返回一个长字符串,而不是16个字符宽的块:

import org.apache.commons.codec.binary.Base64;

public class B64Test {

    public static void main(String[] args) {
        byte[] plaintext = new byte[100];
        String b64text = new Base64().encodeAsString(plaintext);
        System.out.println(b64text);
    }
}

提供输出

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==

如果要将其馈送到openssl中进行解码,则需要提供附加选项-A以使openssl base64在一行上处理数据。请注意,-A需要与-a-base64一起使用,这是同一件事,但可读性更高。 openssl enc的文档对此进行了说明。

或者,您可以告诉Base64()构造函数在例如64个字符之后插入换行符,如下所示:

String b64text = new Base64(64).encodeAsString(plaintext);
相关问题