AES/CBC/PKCS5Padding 解密报错

 

package com.example.demo.test;

import org.apache.tomcat.util.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.*;
import java.security.spec.AlgorithmParameterSpec;

public class AES {
    public static IvParameterSpec getIv() throws UnsupportedEncodingException {
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("utf-8"));
        return ivParameterSpec;
    }
    public static byte[] encrypt(String src, byte[] key) throws NoSuchAlgorithmException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
        SecretKey secretKey = new SecretKeySpec(key, Algorithm);
        IvParameterSpec ivParameterSpec = getIv();
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
        byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName("utf-8")));
        return cipherBytes;
    }
    public static byte[] decrypt(String src, byte[] key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, Algorithm);

        IvParameterSpec ivParameterSpec = getIv();
        Cipher cipher = Cipher.getInstance(AlgorithmProvider);
        cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
        byte[] hexBytes = hexStringToBytes(src);
        byte[] plainBytes = cipher.doFinal(hexBytes);
        return plainBytes;
    }

    public static String toKeyCode(String src) {
        byte key[] = new byte[0];
        String to = null;
        try {
            key = myKey.getBytes("utf-8");
            to = new String(decrypt(src, key), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        }
        return to;
    }

    public static String deKeyCode(String src) {
        byte key[] = new byte[0];
        String to = null;
        try {
            key = myKey.getBytes("utf-8");
            to = byteToHexString(encrypt(src, key));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return to;
    }


    /**
     * 将byte转换为16进制字符串
     *
     * @param src
     * @return
     */
    public static String byteToHexString(byte[] src) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xff;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                sb.append("0");
            }
            sb.append(hv);
        }
        return sb.toString();
    }

    /**
     * 将16进制字符串装换为byte数组
     *
     * @param hexString
     * @return
     */
    public static byte[] hexStringToBytes(String hexString) {
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] b = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return b;
    }

    private static byte charToByte(char c) {
        return (byte) iv.indexOf(c);
    }


    private static String iv = "0102030405060708";//当模式是CBC的时候必须设置偏移量,偏移量字符串:自己随意定义,必须是16位 。
    private static String Algorithm = "AES";
    private static String AlgorithmProvider = "AES/CBC/PKCS5Padding"; //算法/模式/补码方式
    private static String myKey = "e1bfc372ba5a24a3f9637857f115c81e"; //加密解密的秘钥key:自己随意定义。长度为n/8。 n代表的是多少bit


    public static void main(String[] args) throws Exception {
       String src="<response><process_result><return_code>0303</return_code><return_desc>缺少参数</return_desc><trade_no></trade_no></process_result></response>";
       //加密
        byte key[] = myKey.getBytes("utf-8");
        String string = byteToHexString(encrypt(src, key));
        System.out.println(string);
        //  String src2="1dc62b6cd7151b5d5c91af0c13861945533d96082c213d4bb525d703a26ed0a7f164d836b70f8931a454721a668c75049312daee7483fa67f045d44fd1ed017efd8575d13d7d2c43a36cefb7d9d2fbaed96ff174afcb25bffe3a7d3fd861a7c1f408094dd6574b904def1ebec558528916d10c5e18c2bb1c299331ab0b4938248fee999c88a5df9ba071d9b335f5b880fae31ce96f89623ba56815bb85b1d5a2";
        //解密
        byte[] decrypt = decrypt(string,myKey.getBytes("utf-8"));
        System.out.println(new String(decrypt, "utf-8"));



    }

}

 

试一试这个方法  https://blog.csdn.net/qq_38361800/article/details/101295265

可以参考代码  

https://github.com/ouyangpeng/CryptionDemoOnKotlin/blob/master/src/com/oyp/crypt/aes/AESCryptUtil.kt

 

package com.oyp.crypt.aes

import com.oyp.crypt.encode.Base64Util
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

/**
 * 对称加密:AES
 * 特点:可逆,加密速度快,可以加密大文件
 */
object AESCryptUtil {
    //AES/CBC/NoPadding (128)
    //AES 秘钥长度是16位,每位8个字节,所以是  16*8=128

    //   算法/工作模式/填充模式
    //   AES/CBC/NoPadding (128)
    //   AES/CBC/PKCS5Padding(128)
    //   AES/ECB/NoPadding(128)
    //   AES/ECB/PKCS5Padding(128)
    private val TRANSFORMATION = "AES/CBC/PKCS5Padding"
    private val CRYPT_ALGORITHM = "AES"

    private val cipher = Cipher.getInstance(TRANSFORMATION)

    fun encrypt(originContent: String, aesKey: String): String {
        initCipher(aesKey, Cipher.ENCRYPT_MODE)
        // 3、Base64编码 加密后的内容
        return Base64Util.encode(cipher.doFinal(originContent.toByteArray()))
    }

    fun decrypt(encryptContent: String, aesKey: String): String {
        initCipher(aesKey, Cipher.DECRYPT_MODE)
        // 3、Base64解码 解密后的内容
        return String(cipher.doFinal(Base64Util.decode(encryptContent)))
    }

    private fun initCipher(aesKey: String, mode: Int) {
        // 1、初始化AES相关的操作
        val key: SecretKeySpec = initKey(aesKey)
        // 2、初始化cipher对象(参数一:解密模式)
        if (TRANSFORMATION.contains("CBC")) {
            // CBC工作模式需要额外添加参数,否则报错:java.security.InvalidKeyException: Parameters missing
            val iv = IvParameterSpec(aesKey.toByteArray())
            cipher.init(mode, key, iv)
        } else {
            cipher.init(mode, key)
        }
    }

    private fun initKey(aesKey: String): SecretKeySpec {
        return SecretKeySpec(aesKey.toByteArray(), CRYPT_ALGORITHM)
    }
}

fun main(args: Array<String>) {
    // 原文
    val originContent = "欧阳鹏的博客:http://blog.csdn.net/ouyang_peng"
    // 自定义的aes的秘钥
    val aesKey = "1234567812345678"
    val aesEncryptContent = AESCryptUtil.encrypt(originContent, aesKey)
    println("原文为:【${originContent}】 进行aes加密后的内容为:【${aesEncryptContent}】")

    val aesDecryptContent = AESCryptUtil.decrypt(aesEncryptContent, aesKey)
    println("秘文为:【${aesEncryptContent}】 进行aes解密后的内容为:【${aesDecryptContent}】")
}