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

Java实现3DES CBC模式加解密时遇IV长度异常求助

解决Java 3DES CBC模式的IV长度错误问题

嘿,这个错误其实很好解决!咱们先把问题根源理清楚,再一步步修正代码。

错误原因分析

你遇到的java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 8 bytes long,核心原因是3DES(Triple DES)的块大小是8字节(64位),CBC模式要求初始化向量(IV)的长度必须和块大小完全一致。

看你的描述,IV是0000000000000000——这是16个字符的十六进制字符串,正确解码后应该是8字节(每2个十六进制字符对应1字节)。但很大概率你在代码里错误地把这个字符串直接用getBytes()转成了字节数组,这样会得到16字节(每个字符占1字节),自然就不符合要求了。

另外还要注意几个3DES实现的关键点:

  • Java中3DES的算法标识是DESede,完整模式要写DESede/CBC/PKCS5Padding(必须指定填充模式,否则会用默认值导致兼容性问题)
  • 你的密钥DCBA4F836E45BAB04FAB2937454075D9是32个十六进制字符,对应16字节,属于3DES的"两密钥"模式(合法的3DES密钥长度是16或24字节)

修正后的完整代码

下面是包含正确IV处理、密钥转换、加密解密的完整实现,我已经帮你适配了你的参数:

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.DESedeKeySpec;
import java.security.spec.AlgorithmParameterSpec;

public class TripleDESCBCExample {

    // 十六进制转字节数组工具方法
    public static byte[] hexStringToByteArray(String hex) {
        int len = hex.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
                    + Character.digit(hex.charAt(i+1), 16));
        }
        return data;
    }

    // 字节数组转十六进制字符串工具方法
    public static String byteArrayToHexString(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X", b));
        }
        return sb.toString();
    }

    public static void main(String[] args) throws Exception {
        // 你的参数
        String ivHex = "0000000000000000"; // 16个十六进制字符 → 8字节
        String encryptedHex = "DD446C051A83BFD98144C348935C61D81398CF29CCFE1CCD";
        String keyHex = "DCBA4F836E45BAB04FAB2937454075D9";

        // 1. 转换IV为8字节数组(关键!)
        byte[] iv = hexStringToByteArray(ivHex);
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);

        // 2. 转换密钥为16字节数组,生成3DES密钥
        byte[] keyBytes = hexStringToByteArray(keyHex);
        DESedeKeySpec keySpec = new DESedeKeySpec(keyBytes);
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
        SecretKey secretKey = keyFactory.generateSecret(keySpec);

        // 3. 初始化解密器
        Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);

        // 4. 解密并输出结果
        byte[] encryptedBytes = hexStringToByteArray(encryptedHex);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        String decryptedText = new String(decryptedBytes); // 假设明文是UTF-8编码,可根据实际调整

        System.out.println("解密结果: " + decryptedText);
        System.out.println("解密结果十六进制: " + byteArrayToHexString(decryptedBytes));
    }
}

关键修正点说明

  • IV的正确转换:用hexStringToByteArray把十六进制的IV字符串转成8字节数组,而不是直接调用getBytes()
  • 算法完整标识:使用DESede/CBC/PKCS5Padding明确指定模式和填充,避免依赖JVM默认值
  • 密钥处理:通过DESedeKeySpec和SecretKeyFactory生成合法的3DES密钥,而不是直接用SecretKeySpec(虽然也可以,但前者更规范)

如果你运行这段代码,应该就能正常解密了。如果还有其他问题,比如明文编码不对,可以调整new String(decryptedBytes)的字符编码参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 02:27:44