繁体   English   中英

使用充气城堡创建带有预签名数据的PKCS7

[英]create PKCS7 with presigned data using bouncy castle

我想使用PKCS7容器在PDF文件中创建分离的签名。 数据(哈希)已预先使用私钥在其他设备上签名。 我想创建一个包含签名数据以及带有公钥的证书的PKCS7。 如果没有提供私钥并使库对数据进行签名,我似乎无法创建带有弹力城堡的PKCS7。 这似乎不起作用:

        InputStream inStream = new FileInputStream("1_public.pem");
        BufferedInputStream bis = new BufferedInputStream( inStream );

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        List<Certificate> certList = new ArrayList<Certificate>();
        Certificate certificate = cf.generateCertificate(bis);
        certList.add(certificate);
        Store certs = new JcaCertStore(certList);

        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        gen.addCertificates( certs );
        CMSProcessableInputStream msg = new CMSProcessableInputStream( new ByteArrayInputStream( "signedhash".getBytes() ) );

        CMSSignedData signedData = gen.generate(msg, false);
        byte[] pkcs7 = signedData.getEncoded() ) );

我通过提供一个不签名的ContentSigner来做到这一点,实际上非常简单:

        InputStream inStream = new FileInputStream("1_public.pem");
        BufferedInputStream bis = new BufferedInputStream( inStream );

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        List<Certificate> certList = new ArrayList<Certificate>();
        Certificate certificate = cf.generateCertificate(bis);
        certList.add(certificate);
        Store certs = new JcaCertStore(certList);
        CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
        gen.addCertificates( certs );

        final byte[] signedHash = "signedhash".getBytes();

        ContentSigner nonSigner = new ContentSigner() {

            @Override
            public byte[] getSignature() {
                return signedHash;
            }

            @Override
            public OutputStream getOutputStream() {
                return new ByteArrayOutputStream();
            }

            @Override
            public AlgorithmIdentifier getAlgorithmIdentifier() {
                return new DefaultSignatureAlgorithmIdentifierFinder().find( "SHA256WithRSA" );
            }
        };

        org.bouncycastle.asn1.x509.Certificate cert = org.bouncycastle.asn1.x509.Certificate.getInstance(ASN1Primitive.fromByteArray(certificate.getEncoded()));
        JcaSignerInfoGeneratorBuilder sigb = new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build());
        sigb.setDirectSignature( true );
        gen.addSignerInfoGenerator(sigb.build(nonSigner, new X509CertificateHolder(cert)));
        CMSProcessableInputStream msg = new CMSProcessableInputStream( new ByteArrayInputStream( "not used".getBytes() ) );

        CMSSignedData signedData = gen.generate(msg, false);
        byte[] pkcs7 = signedData.getEncoded();

如果“外部签名”是由硬件设备执行的,则它也可能包含“签名属性”。 在这种情况下,代码还必须包含:

AttributeTable signedAttributes = signer.getSignedAttributes();
signerInfoBuilder.setSignedAttributeGenerator(new SimpleAttributeTableGenerator(signedAttributes));     
signatureGenerator.addSignerInfoGenerator(signerInfoBuilder.build(nonSigner, signCertificate));

您还应该删除

signatureGenerator.setDirectSignature(true)

有关完整示例,请参见https://www.len.ro/work/attach-payload-into-detached-pkcs7-signature/ 由于我花了很多时间寻找解决方案,并且这篇文章提供了重要的线索,我认为我应该补充我仍然在文章中缺少的信息。 谢谢。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM