Zzzxb's Blog

你要静心学习那份等待时机的成熟的情绪,也要你一定保有这份等待之外的努力和坚持。

JDK1.8 安全算法找不到的问题 Jun 09, 2025

起因

解决方案

算法不能找到

主要原因就是jdk文件的缺失、或者版本问题。

方案1:使用 BouncyCastle

bcprov-jdk159n-1.70.jar,一步到位就不用再折腾JDK

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.70</version>
</dependency>
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;

@Slf4j
public class AESUtil {

    static {
        try {
            Security.addProvider(new BouncyCastleProvider());
            System.out.println("BouncyCastle provider added successfully");
        } catch (Exception e) {
            System.err.println("Failed to add BouncyCastle provider: " + e.getMessage());
        }
    }

    public static String encryptWithPkcs5Padding(String value, String secretKey, String initVector) {
        if (StringUtils.isBlank(secretKey) || StringUtils.isBlank(initVector) || StringUtils.isBlank(value)) {
            return null;
        }
        try {
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));

            // 强制使用BouncyCastle提供商
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");

            cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
            byte[] encrypted = cipher.doFinal(value.getBytes(StandardCharsets.UTF_8));
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception e) {
            log.error("AESUtil encryptWithPkcs5Padding error", e);
            return null;
        }
    }

    public static String decryptWithPkcs5Padding(String value, String secretKey, String initVector) {
        if (StringUtils.isBlank(secretKey) || StringUtils.isBlank(initVector) || StringUtils.isBlank(value)) {
            return null;
        }
        try {
            SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
            IvParameterSpec iv = new IvParameterSpec(initVector.getBytes(StandardCharsets.UTF_8));

            // 强制使用BouncyCastle提供商
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");

            cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
            byte[] original = cipher.doFinal(Base64.getDecoder().decode(value));
            return new String(original, StandardCharsets.UTF_8);
        } catch (Exception e) {
            log.error("AESUtil decryptWithPkcs5Padding error", e);
            return null;
        }
    }
}

IV长度过长

这个错误是因为JDK的加密策略限制。JDK默认限制了加密密钥的长度,需要安装Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。

方案1:安装JCE无限强度策略文件(推荐)

# 对于JDK 1.8
wget https://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip

# 或者从其他源下载
wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip

# 解压
unzip jce_policy-8.zip

# 备份原文件
cp $JAVA_HOME/jre/lib/security/local_policy.jar $JAVA_HOME/jre/lib/security/local_policy.jar.backup
cp $JAVA_HOME/jre/lib/security/US_export_policy.jar $JAVA_HOME/jre/lib/security/US_export_policy.jar.backup

# 替换新文件
cp UnlimitedJCEPolicyJDK8/local_policy.jar $JAVA_HOME/jre/lib/security/
cp UnlimitedJCEPolicyJDK8/US_export_policy.jar $JAVA_HOME/jre/lib/security/