Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/400.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
AES-128-CBC在Java和Linux中是不同的_Java_Android_Encryption_Openssl_Aes - Fatal编程技术网

AES-128-CBC在Java和Linux中是不同的

AES-128-CBC在Java和Linux中是不同的,java,android,encryption,openssl,aes,Java,Android,Encryption,Openssl,Aes,我想在JAVA和Linux中进行aes-128-cbc加密,但它总是给我不同的结果。 例如,我想解码字符串“my.txt”。在Linux中,我是这样做的: echo -n my.txt | openssl aes-128-cbc -K 6f838655d1bd6312b224d3d1c8de4fe1 -iv 9027ce06e06dbc8b -a 我还将其编码为base64,它给出了以下结果:86M5fwdUpQ3tbFrz0ddHJw== 在Java中,我使用以下方法: public s

我想在JAVA和Linux中进行aes-128-cbc加密,但它总是给我不同的结果。 例如,我想解码字符串“my.txt”。在Linux中,我是这样做的:

  echo -n my.txt | openssl aes-128-cbc -K 6f838655d1bd6312b224d3d1c8de4fe1 -iv 9027ce06e06dbc8b -a
我还将其编码为base64,它给出了以下结果:86M5fwdUpQ3tbFrz0ddHJw==

在Java中,我使用以下方法:

public static String encrypt(String key, String initVector, String value) {
    try {
        IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
        SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

        byte[] encrypted = cipher.doFinal(value.getBytes());
        System.out.println("encrypted string: "
                + Base64.encodeToString(encrypted, Base64.DEFAULT));

        return Base64.encodeToString(encrypted, Base64.DEFAULT);
    } catch (Exception ex) {
        ex.printStackTrace();
    }

    return null;
}
对于相同的数据,它给出了完全不同的结果:vgk6yxCrQ5iLFvHxMtQO7w==

我还尝试使用32符号长度iv的aes-256-cbc。在Linux中,我使用aes-256-cbc,在Android中,我使用Spongy Castle库实现这一目的,但它也给出了不同的结果


我做错了什么?或者您建议选择不同的跨平台加密算法。

参数
-K
-iv
需要十六进制编码字符串。您的密钥长度为32个字符,因此为16字节或128位。您的IV长度为16个字符,因此为8字节或64位。AES/CBC的IV长度必须正好为128位。如果不是,那么它必须以某种方式填充。您的IV很可能会填充0x00字节,以达到128位。在Java中也必须这样做

另一个问题是,您将十六进制编码的密钥和IV视为文本,这意味着您将其视为Java中的256位密钥和128位IV。这可能不是你想要的。在使用之前,您必须对十六进制中的字符串进行解码

让我们使用一个虚构的
byte[]fromHex(String hexStr)
实现:


-K
-iv
参数需要十六进制编码字符串。您的密钥长度为32个字符,因此为16字节或128位。您的IV长度为16个字符,因此为8字节或64位。AES/CBC的IV长度必须正好为128位。如果不是,那么它必须以某种方式填充。您的IV很可能会填充0x00字节,以达到128位。在Java中也必须这样做

另一个问题是,您将十六进制编码的密钥和IV视为文本,这意味着您将其视为Java中的256位密钥和128位IV。这可能不是你想要的。在使用之前,您必须对十六进制中的字符串进行解码

让我们使用一个虚构的
byte[]fromHex(String hexStr)
实现:


由于AES是一个定义明确且众所周知的标准,因此算法实际上是相同的。我敢肯定,问题在于投入。各种输入(键、iv、数据)的实际字节是否相同?请注意,字节和字符不是一回事。字符集或编码是它们之间的关系。此外,请验证您对.、等使用的填充是否相同。由于AES是一个定义明确且众所周知的标准,因此算法实际上是相同的。我敢肯定,问题在于投入。各种输入(键、iv、数据)的实际字节是否相同?请注意,字节和字符不是一回事。字符集或编码是它们之间的关系。另外,请验证您是否对这两个字符使用了相同的填充。是的,我的初始iv长度为32个字符,但它给了我有关iv长度的错误,现在我明白了原因。是的,fromHex()正在工作,它会给出正确的结果。非常感谢。是的,我最初的iv是32个字符长,但它给了我关于iv长度的错误,现在我明白了原因。是的,fromHex()正在工作,它会给出正确的结果。非常感谢。
byte[] ivBytes = new byte[16];
byte[] ivBytesShort = fromHex(initVector);
System.arraycopy(ivBytesShort, 0, ivBytes, 0, ivBytesShort.length);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
SecretKeySpec skeySpec = new SecretKeySpec(fromHex(key), "AES");