You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java指定密钥IV实现AES-256-CBC加密后OpenSSL解密失败排查

问题分析与解决

核心错误原因

你的Java代码与OpenSSL命令的密钥/IV处理逻辑完全不匹配,导致解密失败:

  • 字节转换逻辑错误:OpenSSL的-K和-iv参数会将输入的十六进制字符串直接解析为字节数组(例如"a1b2"会被解析为0xa1, 0xb2两个字节),但你代码中是把十六进制字符串本身的字节(例如"a1b2"转成0x61, 0x31, 0x62, 0x32四个字节)作为密钥/IV使用,两者完全不对应。
  • 长度不符合要求:
    • AES-256加密需要32字节(256位)的密钥,对应的十六进制字符串长度必须是64位(每个字节对应2个十六进制字符)。
    • AES-CBC模式的IV必须是16字节,对应的十六进制字符串长度必须是32位。

修正后的Java代码

使用十六进制字符串解析为字节数组的方式生成密钥和IV,同时保证长度符合要求:

import org.apache.commons.io.IOUtils;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

public class OpenSslEncryptor {

    public static void main(String... args) throws Exception {

        // AES-256需要64位十六进制字符串(对应32字节密钥);IV需要32位十六进制字符串(对应16字节)
        String keyHex = generateRandomHex(64);
        String ivHex = generateRandomHex(32);

        // 将十六进制字符串解析为字节数组,匹配OpenSSL的处理逻辑
        byte[] keyBytes = Hex.decodeHex(keyHex);
        byte[] ivBytes = Hex.decodeHex(ivHex);

        // 准备待加密文件
        File baseFile = new File("hello.txt");
        IOUtils.write("hello openssl !", new FileOutputStream(baseFile), StandardCharsets.UTF_8);
        byte[] inBytes = new FileInputStream(baseFile).readAllBytes();

        // 初始化AES-CBC加密器
        final SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(ivBytes));

        // 执行加密并写入文件
        byte[] encryptedData = cipher.doFinal(inBytes);
        File outputFile = new File(baseFile.getAbsolutePath() + ".ssl");
        IOUtils.write(encryptedData, new FileOutputStream(outputFile));

        // 生成可直接执行的OpenSSL解密命令
        String decryptCommand = "openssl aes-256-cbc -d -K " + keyHex
                + " -iv " + ivHex
                + " -in " + outputFile.getName()
                + " -out hello-clear.txt";

        System.out.println(decryptCommand);
    }

    // 生成指定长度的随机十六进制字符串
    private static String generateRandomHex(int length) {
        SecureRandom secureRandom = new SecureRandom();
        StringBuilder builder = new StringBuilder(length);
        for (int i = 0; i < length; i++) {
            builder.append(Integer.toHexString(secureRandom.nextInt(16)));
        }
        return builder.toString();
    }
}

补充说明

  • 若不想引入Apache Commons Codec依赖,可自行实现十六进制字符串转字节数组的方法:
private static byte[] hexStringToByteArray(String s) {
    int len = s.length();
    byte[] data = new byte[len / 2];
    for (int i = 0; i < len; i += 2) {
        data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
                             + Character.digit(s.charAt(i+1), 16));
    }
    return data;
}
  • 运行修正后的代码后,生成的解密命令可直接在终端执行,不会再出现密钥/IV不匹配的错误。

内容的提问来源于stack exchange,提问作者wishper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:05:22