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

BouncyCastle冲突场景下解密加密p8格式RSA私钥的替代方案咨询

问题描述

我通过命令行使用openSSL生成RSA私钥,执行命令如下:

$ openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8

生成的私钥为加密p8格式文件,需要使用密码解密得到可用的PrivateKey对象用于身份认证。此前我使用如下可正常运行的BouncyCastle代码实现该需求:

public static PrivateKey getKey()
            throws Exception {
         String filename = "C:\Snowflake\rsa_key.p8";
         Security.addProvider(new BouncyCastleProvider());
        PrivateKeyInfo privateKeyInfo = null;
        Security.addProvider(new BouncyCastleProvider());
        // Read an object from the private key file.
         PEMParser pemParser = new PEMParser(new FileReader(Paths.get(filename).toFile()));
            Object pemObject = pemParser.readObject();
        if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) {
            // Handle the case where the private key is encrypted.
            PKCS8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = (PKCS8EncryptedPrivateKeyInfo) pemObject;
            String passphrase = getPrivateKeyPassphrase();
            InputDecryptorProvider pkcs8Prov = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(passphrase.toCharArray());
            privateKeyInfo = encryptedPrivateKeyInfo.decryptPrivateKeyInfo(pkcs8Prov);
        } else if (pemObject instanceof PrivateKeyInfo) {
            // Handle the case where the private key is unencrypted.
            privateKeyInfo = (PrivateKeyInfo) pemObject;
        }
        pemParser.close();
        JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
        return converter.getPrivateKey(privateKeyInfo);
    }

但目前bouncycastle的bckpix.jar与bcfips.jar存在冲突,运行时报NoSuchField错误,无法使用BouncyCastle相关组件,请问有没有替代BouncyCastle实现该需求的方案?
以下是密码为"520759"的加密私钥示例:

-----BEGIN ENCRYPTED PRIVATE KEY-----
MIIFLTBXBgkqhkiG9w0BBQ0wSjApBgkqhkiG9w0BBQwwHAQIuo49Vz6fm/MCAggA
MAwGCCqGSIb3DQIJBQAwHQYJYIZIAWUDBAEqBBAag5K2dYPcW8RoOrg9CfyuBIIE
0M3n8NyQrgmkg9nHPp+qsW8OCPp/ezLR6j1jvo2Rj5/BCRdmFEFLu4S1v9x9ZTDt
CTcq+P8TOeLWgQ1um2Ty8INc4uG5ms0fpvoJ7gIaysnw9vpI/jlhwC3X6xaInWEZ
cU8oU3daz3aHCtgpjulr3Dno3Uj8JadYyoGdSe/ADECHqU3rfqNyOiLWjGx9Se8F
u3LjlM5u/y8KIu25wRHkGho3Rv/0Ns+KOroiIQ3Tdt1AxKAchPfr+MeOA/zH3qJq
IItAxycZG4PL0W70vjYnywzA0go5KgJnq39yDuIYeL7Uj3ygZyKLQEXugiC/eVnH
9ESlTesbGlw6QYlzfD6xPCLG/weT860tuWUCbx9cniZkG0CqHySiSHN0G6H1P+ZS
gTPgiBVBq7hsg0D2BPF3+3DNPhDjuBS/92fR2DPpNayu19tc7HoEnaT9CXSyq4L4
e71N5ybspYmrc+jqFdJEl3rZEKEYzIfmWNADgnmj+/deJl02JIgcyML49v04+ZB2
MrZTQCMC616ErnwmR3iaj2gkgs7IYsSHBAiAZulJWJISQstsKM1TB22ldCFwVT48
MIWG/2XCl4d9+e2beqDy1Jr12VGbdmx/4H20VMsinutGzDKY9JrP6QzLdCQ+/V5j
1ORgar0fewFVlyUBcbWYn8kdY07hZtfV0dW9TV5RLTDK1j9YOSofHW/fHQiTCBwT
jtZUlgFiZCYr9N0Y3pYLcYjwaya9V3rITIp5SCnVXzLMz9TVur8DlgLYwIxW0nhl
QsU/30K9QqM8bq5Iw+I4GD0FqlbO85XelePL4n1eXGERAqbkEZjoNzyoz4hizoX1
kddvcrYi9BNowU5qvJPcbgZ68aupLkljP8le88qv7aAY6Aou6gT64WvbyQA7dpcw
K19cLGbhvNnRGC1Tgj5SB+CzXZZg5iUuFGEXLqreiXdUP8DTOE/uxWBCY/57j6+0
JzFXf0CoqYleGKplkKTjZzF/gorf6RjXiW2bZa2a3c/hhGaslyqCSmX57NWFqjun
N89PnPO8Z8JND1h7wDk8cP9M6rlJiW9BCMTJujNqQaojeeurfWKEsSIPdtEbDTEh
XHSPvLvEJ72Hes7hfpMqiaBuLcm5H7vnNCPXxBbC0Cdwk/yw2S4Mu16nC0HFzSLr
ZzgaKkS0NcrTNOIeY6UhKiJbJgJw9gE6dDEoCbvBy2BsiezAbf6nFO852iW1R1q7
XcRXi0FmBr5UnZusSvxZEHwzcitIV6qdbzeVpNSJUssoBIOaXdsfKGnY4AG9nXXO
8LCPkBBIGXD3amLCPTBKt7XrAgsvCAM+0I07/VGUoKq8p3J62it2/WOdwBAFS0me
tEaIJQVnD2OocFWSxj1UHuBqDaAoCa1dXk2FjlB6jP3p4fhMOooPj/Z+IOYa4Tfr
fgCcLDvVo4sDCAwyExDA7V/zJGa4fRIzyO+iv4q9+aobojhLnFWhxII7e2SdYnGy
5TKLC1hFhBVbv37TOQL0X3W5dnJJXRfhcv2Rce8OqfD1JKDXDETsIrgbTrq2IrPX
ISgdvb6xcC2tD8/7Fo7CC+tMHm5uun9z0rnZIl7ZAuVXA0cfd9cRCp6eksnbc6KR
nhZnW2zER1ABUa9Oq0xqWooAzKd4Ez8Ck/ZKpcC7Nz4o
-----END ENCRYPTED PRIVATE KEY-----
解决方案

可直接使用JDK原生API实现需求,无任何第三方依赖,完全避免BouncyCastle相关的jar包冲突问题,完整实现代码如下:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;

public class RsaKeyLoader {

    public static PrivateKey getKey(String keyFilePath, char[] passphrase) throws Exception {
        // 1. 读取PEM文件内容,处理格式
        String pemContent = Files.readString(Paths.get(keyFilePath));
        // 去除头尾标记和所有换行、空格
        String encodedKey = pemContent
                .replace("-----BEGIN ENCRYPTED PRIVATE KEY-----", "")
                .replace("-----END ENCRYPTED PRIVATE KEY-----", "")
                .replaceAll("\\s+", "");
        // Base64解码得到DER二进制内容
        byte[] encryptedKeyBytes = Base64.getDecoder().decode(encodedKey);

        // 2. 解析加密的PKCS8私钥
        EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(encryptedKeyBytes);
        // 生成解密用的密钥
        PBEKeySpec pbeKeySpec = new PBEKeySpec(passphrase);
        SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(encryptedPrivateKeyInfo.getAlgName());
        // 3. 解密得到明文私钥的编码
        PKCS8EncodedKeySpec keySpec = encryptedPrivateKeyInfo.getKeySpec(secretKeyFactory.generateSecret(pbeKeySpec));

        // 4. 生成RSA私钥对象
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        return keyFactory.generatePrivate(keySpec);
    }

    // 测试用例
    public static void main(String[] args) throws Exception {
        PrivateKey privateKey = getKey("C:\\Snowflake\\rsa_key.p8", "520759".toCharArray());
        System.out.println("私钥加载成功,算法:" + privateKey.getAlgorithm());
    }
}

说明

  • 该实现兼容JDK 8及以上所有版本,不需要引入任何额外jar包
  • 同时支持你生成的加密PKCS8格式私钥,也可扩展支持未加密的PKCS8私钥(直接解析PKCS8EncodedKeySpec即可)
  • 你提供的示例私钥可通过上述代码正常解密使用

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 06:21:02