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

Java 17下基于Bouncycastle从PEM格式RSA公钥生成Key对象方案

兼容Java 17的RSA公钥转Java Key对象方案(基于Bouncycastle)

原代码依赖的sun.security.util.DerInputStream和DerValue属于JDK内部API,Java 9起被标记为禁用,以下是基于Bouncycastle库的替代实现,完全兼容Java 17+。

方案一:对齐原代码逻辑的手动解析

这种方式和你原代码的解析逻辑一致,只是替换为Bouncycastle的公开ASN.1解析类:

import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.pkcs.RSAPublicKey;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;

// ... 业务代码
String keyData = r.getPublicKey()
        .replace("-----BEGIN RSA PUBLIC KEY-----", "")
        .replace("-----END RSA PUBLIC KEY-----", "")
        .replaceAll("\\s+", ""); // 清理所有空白字符,避免解析异常

byte[] content = Base64.getDecoder().decode(keyData);

try (ASN1InputStream asn1InputStream = new ASN1InputStream(content)) {
    // 直接用Bouncycastle的RSAPublicKey类解析PKCS#1格式的公钥
    RSAPublicKey rsaPublicKey = RSAPublicKey.getInstance(asn1InputStream.readObject());
    
    BigInteger modulus = rsaPublicKey.getModulus();
    BigInteger publicExp = rsaPublicKey.getPublicExponent();

    KeyFactory kf = KeyFactory.getInstance("RSA");
    RSAPublicKeySpec keySpec = new RSAPublicKeySpec(modulus, publicExp);
    PublicKey pk = kf.generatePublic(keySpec);
    
    // 使用生成的公钥pk
} catch (Exception e) {
    throw new RuntimeException("解析RSA公钥失败", e);
}

方案二:更简洁的PEM直接读取

利用Bouncycastle的PEMParser可以直接处理带头的PEM格式公钥,省去手动替换头和Base64解码的步骤:

import org.bouncycastle.asn1.pkcs.RSAPublicKey;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.openssl.PEMParser;
import java.io.StringReader;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;

// ... 业务代码
String publicKeyStr = r.getPublicKey();

try (StringReader reader = new StringReader(publicKeyStr);
     PEMParser pemParser = new PEMParser(reader)) {
    Object pemObject = pemParser.readObject();
    PublicKey pk;
    KeyFactory kf = KeyFactory.getInstance("RSA");
    
    if (pemObject instanceof SubjectPublicKeyInfo) {
        // 处理X.509格式公钥(BEGIN PUBLIC KEY)
        SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) pemObject;
        pk = kf.generatePublic(new X509EncodedKeySpec(spki.getEncoded()));
    } else if (pemObject instanceof RSAPublicKey) {
        // 处理PKCS#1格式公钥(BEGIN RSA PUBLIC KEY)
        RSAPublicKey rsaPublicKey = (RSAPublicKey) pemObject;
        pk = kf.generatePublic(new RSAPublicKeySpec(rsaPublicKey.getModulus(), rsaPublicKey.getPublicExponent()));
    } else {
        throw new IllegalArgumentException("不支持的公钥格式");
    }
    
    // 使用生成的公钥pk
} catch (Exception e) {
    throw new RuntimeException("解析RSA公钥失败", e);
}

核心替换点

  • 原sun.security.util.DerInputStream → org.bouncycastle.asn1.ASN1InputStream
  • 原手动解析DER序列 → 直接用org.bouncycastle.asn1.pkcs.RSAPublicKey封装解析逻辑,减少出错概率
  • 方案二的PEMParser支持直接读取标准PEM格式,代码更简洁健壮

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:23:24