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

Java 8迁移至Java 17遇sun.security包不可见问题求解决方案

解决Java 8迁移至Java 17时PKCS#10相关内部API不可用问题

问题原因

你依赖的sun.security.pkcs10.PKCS10和sun.security.x509.X500Name属于Java内部私有API,从Java 9开始就被标记为受限访问,Java 17中已完全移除,因此编译和运行时会出现包不可见的错误。

推荐解决方案:使用BouncyCastle密码学库替代

BouncyCastle是业界广泛认可的开源密码学库,提供了完整且稳定的PKCS#10证书请求生成支持,不受Java版本迭代影响。

步骤1:添加BouncyCastle依赖

如果使用Maven,在pom.xml中添加:

<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcpkix-jdk15on</artifactId>
    <version>1.77</version> <!-- 建议使用最新稳定版 -->
</dependency>

步骤2:替换原有实现代码

以下代码完全替代原逻辑,生成与原代码格式一致的PEM编码PKCS#10请求:

import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.cert.jcajce.JcaPKCS10CertificationRequestBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
import org.bouncycastle.util.io.pem.PemWriter;
import java.io.StringWriter;
import java.security.KeyPair;
import java.security.Security;
import java.security.cert.X500Principal;
import java.nio.charset.StandardCharsets;

private static byte[] encodeAndSignRequest(KeyPair keyPair, String signatureAlgorithm, X500Principal principal) throws Exception {
    // 注册BouncyCastle安全提供者
    Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

    // 转换X500Principal为BouncyCastle的X500Name
    X500Name subject = new X500Name(principal.getName());

    // 创建签名器
    ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithm)
            .setProvider("BC")
            .build(keyPair.getPrivate());

    // 构建PKCS#10证书请求
    JcaPKCS10CertificationRequestBuilder requestBuilder = new JcaPKCS10CertificationRequestBuilder(subject, keyPair.getPublic());
    PKCS10CertificationRequest pkcs10Request = requestBuilder.build(contentSigner);

    // 编码为PEM格式(与原代码输出格式一致)
    StringWriter writer = new StringWriter();
    try (PemWriter pemWriter = new PemWriter(writer)) {
        pemWriter.writeObject(new org.bouncycastle.util.io.pem.PemObject("CERTIFICATE REQUEST", pkcs10Request.getEncoded()));
    }

    return writer.toString().getBytes(StandardCharsets.UTF_8);
}

代码说明

  • 移除了对Signature参数的直接依赖,改为传入签名算法字符串(如SHA256withRSA),更符合BouncyCastle的API设计;若需保留原参数,可通过signature.getAlgorithm()获取算法字符串。
  • 使用PemWriter生成标准PEM格式的证书请求,与原代码pkcs10.print(printStream)的输出格式完全一致。
  • BouncyCastle的API均为公开稳定接口,不会因Java版本升级出现兼容性问题。

不推荐的临时方案

若因特殊情况需临时兼容,可通过JVM启动参数--add-exports java.base/sun.security.pkcs10=ALL-UNNAMED和--add-exports java.base/sun.security.x509=ALL-UNNAMED强制开放内部API,但该方案违反Java封装原则,后续Java版本可能彻底失效,不建议长期使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:08:32