今天在写AES加密算法时,测试过程中运行报错提示:Cannot find any provider supporting AES/CBC/PKCS7Padding,找不到这个AES/CBC/PKCS7Padding,经百度查询得知,原生JDK不支持这个,所以需要在JDK里面添加一个支持的这个算法的jar包。

添加jar包

下载bcprov-jdk16-1.46.jar

添加到jdk目录 jdk_path/jre/lib/ext

配置生效

修改 jdk_path/jre/lib/security/java.security,在里面搜索 sasl.Provider,就可以定位到需要修改的位置

# security.provider.7=com.sun.security.sasl.Provider  # 注释这一行
security.provider.7=org.bouncycastle.jce.provider.BouncyCastleProvider # 添加这一行

Maven依赖

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk16</artifactId>
    <version>1.46</version>
</dependency>

AES加密代码

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESUtilS {

    // 使用AES-128-CBC加密模式,key需要为16位,key和iv可以相同,也可以不同!
    private static final String KEY = "9!#95hsup*&$1zq7";
    private static final String IV = "0000000000000000";

    public static final String algorithm = "AES";
    private static final String CIPHER_ALGORITHM_CBC = "AES/CBC/PKCS7Padding";

    static {
        // BouncyCastle是一个开源的加解密解决方案,主页在http://www.bouncycastle.org/
        Security.addProvider(new BouncyCastleProvider());
    }

    /**
     * 加密方法 返回base64加密字符串
     * 和前端保持一致
     *
     * @param data 要加密的数据
     * @param key  加密key
     * @param iv   加密iv
     * @return 加密的结果
     * @throws Exception
     */
    public static String encrypt(String data, String key, String iv) throws Exception {
        try {
            // 获取Cipher
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
            // 生成密钥
            SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), algorithm);
            // 指定模式(加密)和密钥
            // 创建初始化向量
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
            // cipher.init(Cipher.ENCRYPT_MODE, keySpec);
            // 加密
            byte[] bytes = cipher.doFinal(data.getBytes());
            return encryptBASE64(bytes);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 解密方法
     *
     * @param data 要解密的数据
     * @param key  解密key
     * @param iv   解密iv
     * @return 解密的结果
     * @throws Exception
     */
    public static String decrypt(String data, String key, String iv) throws Exception {
        try {
//            byte[] encrypted1 = new Base64().decode(data);
            Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_CBC);
            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), algorithm);
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
            byte[] original = cipher.doFinal(decryBASE64(data));
            return new String(original);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 使用默认的key和iv加密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static String encrypt(String data) throws Exception {
        return encrypt(data, KEY, IV);
    }

    /**
     * 使用默认的key和iv解密
     *
     * @param data
     * @return
     * @throws Exception
     */
    public static String decrypt(String data) throws Exception {
        return decrypt(data, KEY, IV);
    }


    /***
     * BASE64解密
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decryBASE64(String key) throws Exception {
        return (new BASE64Decoder()).decodeBuffer(key);
    }

    /***
     * BASE64加密
     * @param key
     * @return
     * @throws Exception
     */
    public static String encryptBASE64(byte[] key) throws Exception {
        return (new BASE64Encoder()).encode(key);
    }

    public static void main(String[] args) throws Exception {
        String encrypt = encrypt("你好!");
        String decrypt = decrypt(encrypt);
        System.out.println("密文:" + encrypt);
        System.out.println("原文本:" + decrypt);
    }
}