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

Java使用新版BouncyCastle库解码PKCS#7字符串的方案咨询

问题原因

类型转换异常由解析逻辑错误导致:
PEMParser读取-----BEGIN PKCS7-----标识的PEM内容时,返回值是PKCS7结构对应的org.bouncycastle.asn1.cms.ContentInfo实例,并非X509Certificate对象。旧版PEMReader内置的自动类型转换逻辑在新版API中被拆分,需要手动完成CMS结构解析和证书提取步骤,不能直接强转。
当前使用的bcpkix-jdk15on:1.58版本完全支持正确解析逻辑,无需升级依赖。

完整实现代码
import org.bouncycastle.asn1.cms.ContentInfo;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import java.io.StringReader;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.util.Collection;

public class Pkcs7Decoder {
    public static void main(String[] args) throws Exception {
        // 注册BouncyCastle安全提供者
        if (Security.getProvider(BouncyCastleProvider.PROVIDER_NAME) == null) {
            Security.addProvider(new BouncyCastleProvider());
        }

        // 待解析的PKCS7格式PEM内容
        String pkcs7Pem = "-----BEGIN PKCS7-----\n" +
                "MIIC5wYJKoZIhvcNAQcCoIIC2DCCAtQCAQExADALBgkqhkiG9w0BBwGgggK8MIICuDCCAl6gAwIB\n" +
                "AgIQXCpspdawOszPHWPu6BzK7DAKBggqhkjOPQQDAjBAMQswCQYDVQQGEwJERTEUMBIGA1UEChML\n" +
                "U29mdHdhcmUgQUcxGzAZBgNVBAMTElFBIFRoaW4tRWRnZSBDQSBHMTAeFw0yMjA2MjIwNzM1MDJa\n" +
                "Fw0yNTA2MjIwNzM1MDJaMCUxIzAhBgNVBAMTGlJlcXVlc3RlZCBUZXN0IENlcnRpZmljYXRlMIIB\n" +
                "IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjahV4/HclaS48gxI6ojGk1WZsBr+oS2PwAG5\n" +
                "abWG1ilmOGakfSoJt5exz3+vfbqX9Wewge7kE+2ehM3kyhLxtRLc9o2IbvbRsonyncIhb0SqJ+6j\n" +
                "oTK8b7Dd1XwTFNLMNpQK2trY6c0ScBrdJarPv0QKszlpJHpFCCjozlaExdFKeYINUzSN6UKMd9Kw\n" +
                "L6T/3QPOQSBLVAwKnBC8dZnxmoG8Nr0XOJE0FBDISnB/PkE70w8bTqquCCqdWInFZJkZog+QsYBu\n" +
                "LDZq5ODeoUfSrkfnrR1xudgS5/OYRsU5jfwU5h4D1bM1MSQAMseOalFO+Iv5tm4tszNF3HNwSn8N\n" +
                "KQIDAQABo4GJMIGGMBMGA1UdJQQMMAoGCCsGAQUFBwMCMBMGA1UdIwQMMAqACEhBtjq9T25cMAsG\n" +
                "A1UdDwQEAwIFoDBNBgNVHR8ERjBEMEKgQKA+hjxodHRwOi8vZHAuMzgucWEuZ28ubmV4dXNncm91\n" +
                "cC5jb20vY3JsL3FhX3RoaW4tZWRnZV9jYV9nMS5jcmwwCgYIKoZIzj0EAwIDSAAwRQIhALgVQ4GE\n" +
                "NDd3KkjDjDE1a3Kn5FzjTWVjDc4ZdCsJvm1yAiBHdeGu8Sklq57MM1eSMMS7C4KvAYepzPkM4/9s\n" +
                "vgRT8zEA\n" +
                "-----END PKCS7-----";

        // 解析PEM结构
        PEMParser pemParser = new PEMParser(new StringReader(pkcs7Pem));
        ContentInfo contentInfo = (ContentInfo) pemParser.readObject();
        pemParser.close();

        // 构造PKCS7签名数据对象
        CMSSignedData signedData = new CMSSignedData(contentInfo);

        // 提取结构内嵌入的所有证书
        Collection<X509CertificateHolder> certHolders = signedData.getCertificates().getMatches(null);
        JcaX509CertificateConverter certConverter = new JcaX509CertificateConverter()
                .setProvider(BouncyCastleProvider.PROVIDER_NAME);
        for (X509CertificateHolder holder : certHolders) {
            X509Certificate cert = certConverter.getCertificate(holder);
            // 可直接使用标准X509Certificate对象完成后续操作
            System.out.println("证书主题:" + cert.getSubjectX500Principal().getName());
            System.out.println("证书颁发者:" + cert.getIssuerX500Principal().getName());
        }
    }
}
关键说明
  • 只有-----BEGIN CERTIFICATE-----开头的单证书PEM内容,才能将PEMParser.readObject()的返回值直接转换为证书对象,其余格式(PKCS7、CSR、私钥等)都需要按照对应ASN.1结构做二次解析。
  • 上述代码会提取PKCS7结构中嵌入的所有证书,如果内容包含完整证书链,会一次性返回链上所有证书,按需取用即可。
  • 如果后续升级BouncyCastle到1.69+版本,bcpkix-jdk15on包会改名为bcpkix-jdk18on,类路径和API逻辑无变化,上述代码可直接运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:51:37