Bouncy Castle:与现有CA签署的证书 [英] Bouncy Castle: Signed Certificate with an existing CA

查看:199
本文介绍了Bouncy Castle:与现有CA签署的证书的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个证书(A),该证书针对存储在p12密钥库中的其他证书(B)进行了签名。此存储的证书(B)已添加到我的本地计算机的受信任证书存储中。

I'm trying to create a certificate (A) which is signed for other certificate (B) stored in a p12 keystore. This stored certificate (B) was added to the trusted certificate store of my local machine.

证书A用于使用充气城堡1.52库对pdf文档进行签名,但是我在签名文档中获得的数字签名无效。

Certificate A is used to sign a pdf document using bouncy castle 1.52 library, but the digital signature that I obtain in the signed document is invalid.

我将解释仅在有人可以帮助我的情况下完成的步骤。

I'm going to explain the steps done just if somebody can help me.

首先,我从p12密钥库创建CSR (B):

First, I create a CSR from the p12 keystore(B):

    private static PKCS10CertificationRequest generateCSR() {
    PKCS10CertificationRequest csr = null;
    try {
        initCACert();
        PKCS10CertificationRequestBuilder p10Builder = new JcaPKCS10CertificationRequestBuilder(
                new X500Principal("CN=Requested Test Certificate"), CAcert.getPublicKey());
        JcaContentSignerBuilder csBuilder = new JcaContentSignerBuilder("SHA256withRSA");
        ContentSigner signer = csBuilder.build(CApk);
        csr = p10Builder.build(signer);
    } catch (Exception e) {
        log.error(e);
    }
    return csr;
}

然后,使用此CSR生成了证书(A)。

Then, a certificate was generated (A) with this CSR.

    private static Certificate signCSR() throws Exception { 
    PKCS10CertificationRequest csr = generateCSR();

    AlgorithmIdentifier sigAlgId = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA256withRSA");
    AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId);

    X500Name issuer = X500Name.getInstance(CAcert.getSubjectX500Principal().getEncoded());

    BigInteger serial = new BigInteger(32, new SecureRandom());
    Calendar c = Calendar.getInstance();
    c.add(Calendar.SECOND, -1);
    Date from = c.getTime();
    c.add(Calendar.YEAR, 5);
    Date to = c.getTime();

    X509v1CertificateBuilder certBuilder = new X509v1CertificateBuilder(issuer, serial, from, to, csr.getSubject(),
            csr.getSubjectPublicKeyInfo());

    ContentSigner signer = new BcRSAContentSignerBuilder(sigAlgId, digAlgId)
            .build(PrivateKeyFactory.createKey(CApk.getEncoded()));
    X509CertificateHolder holder = certBuilder.build(signer);

    CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
    InputStream in = new ByteArrayInputStream(holder.getEncoded());
    Certificate cert = certFactory.generateCertificate(in);

    return cert;
}

最后,我使用生成的证书(A)对我的pdf签名。 / p>

Finally, I use this generated certificate (A) to sign my pdf.

        Certificate cert = signCSR();

        SignerInfoGeneratorBuilder signerInfoBuilder = new SignerInfoGeneratorBuilder(
                    new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()
                    );
        signerInfoBuilder.setSignedAttributeGenerator( signedAttributeGenerator );

        JcaContentSignerBuilder contentSignerBuilder = new JcaContentSignerBuilder( "SHA1WITHRSA" );
        contentSignerBuilder.setProvider("BC");


        X509CertificateHolder certificateHolder = new X509CertificateHolder( cert.getEncoded( ) );

        generator.addSignerInfoGenerator(
                signerInfoBuilder.build( contentSignerBuilder.build( CApk ),
                        certificateHolder ) 
                );

        ArrayList<X509CertificateHolder> signingChainHolder = new ArrayList<X509CertificateHolder>( );
        certificateHolder = new X509CertificateHolder( cert.getEncoded() );
        certificateHolder = new X509CertificateHolder( CAcert.getEncoded() );

        signingChainHolder.add( certificateHolder );

        Store certs = new JcaCertStore( signingChainHolder );
        generator.addCertificates( certs );

        CMSTypedData content = new CMSProcessableByteArray(datos);

        CMSSignedData signedData = generator.generate( content, true );
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        new DEROutputStream(baos).writeObject(signedData.toASN1Structure());
        result = baos.toByteArray();

所有过程显然都正确执行,但是当我打开pdf时,签名无效:

All the process is executed apparently right, but when I open the pdf the signature is invalid:

编辑:我做了一个导出生成的证书。这是获得的结果。

I have made an export of the generated certificate. This is the result obtained.

< img src = https://i.stack.imgur.com/RV3bb.png alt =在此处输入图片描述>

我会感谢任何可以帮助我解决此问题的评论或信息。

I will appreciate any comment or information that can help me to fix this.

预先感谢。

推荐答案

我已经发现了问题:我正在按照相反的顺序构建证书链。

I have identified the problem: I was building the certificate chain in the opposite order that should be.

我有以下顺序:

 certificateHolder = new X509CertificateHolder( cert.getEncoded() );
 certificateHolder = new X509CertificateHolder( CAcert.getEncoded() );

正确的顺序是:

certificateHolder = new X509CertificateHolder( CAcert.getEncoded() );
certificateHolder = new X509CertificateHolder( cert.getEncoded() );

我希望有人可以找到有用的信息!

I hope somebody can find this information useful!

这篇关于Bouncy Castle:与现有CA签署的证书的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆