具有CBC模式的三重DES:java.security.InvalidAlgorithmParameterException:错误的IV长度:必须长度为8个字节

时间:2018-04-11 12:13:38

标签: java encryption 3des cbc-mode block-cipher

我正在尝试在java中使用CBC模式实现3DES加密/解密。

初始化向量为0000000000000000
加密字符串为DD446C051A83BFD98144C348935C61D81398CF29CCFE1CCD
解密密钥为DCBA4F836E45BAB04FAB2937454075D9

我收到以下错误。 任何帮助都感激不尽。感谢。

java.security.InvalidAlgorithmParameterException: Wrong IV length: must be 8 bytes long

代码:

import java.security.Key; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.DESedeKeySpec; 
import javax.crypto.spec.IvParameterSpec;

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

public class DES3 { 

    private static final String IV = "01234567"; 
    private static final String CHARSET = "utf-8"; 

    public static String decrypt(String iv, String secretKey, String encryptText) throws Exception { 
        DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes()); 
        SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede"); 
        Key deskey = keyfactory.generateSecret(spec); 
        Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding"); 
        IvParameterSpec ips = new IvParameterSpec(iv.getBytes()); 
        cipher.init(Cipher.DECRYPT_MODE, deskey, ips); 
        byte[] decryptData = cipher.doFinal(Base64.decodeBase64(encryptText)); 
        return new String(decryptData, CHARSET); 
    } 

    public static String decrypt(String secretKey, String encryptText) throws Exception { 
        return decrypt(IV, secretKey, encryptText); 
    } 

    public static void main(String[] args) {

        try {
            String iv="0000000000000000";
            System.out.println("iv size"+iv.getBytes("UTF8").length);
            decrypt(iv, "DCBA4F836E45BAB04FAB2937454075D9", "DD446C051A83BFD98144C348935C61D81398CF29CCFE1CCD");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

1 个答案:

答案 0 :(得分:2)

你的问题在这里:

 String iv="0000000000000000";

表示您的IV是十六进制字符串。但是在您的解密功能中,您使用:

iv.getBytes()

这个IV。这显然超过16个字节。 您需要将十六进制字符串转换为字节,而不仅仅使用getBytes()函数getBytes()将每个聊天转换为相应的ASCII代码,因此每个0x30将获得一个16字节的数组,而不是每个0获得一个8字节的数组。

顺便说一下,你的密钥和输入也有同样的问题。

您可以在此处查看hexStringToByteArray()