java - 使用 bouncy caSTLe 使用预签名数据创建 PKCS7

标签 java bouncycastle pkcs#7

我想使用 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();

关于java - 使用 bouncy caSTLe 使用预签名数据创建 PKCS7,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39378249/

相关文章:

java - 具有相同公钥的服务器和客户端 SSL 证书

c++ - 如何在 Linux 中进行密码学(数字签名)

java - QESeal LTV 验证

java - 是否应该重用 ModelMapper 实例以利用缓存的 TypeMap?

java - 如何将 PublicKey 转换为 OpenSSHauthorized_keys 格式

java - 以 web.xml 以外的方式启用/禁用 servlet

java - BouncycaSTLe的CMac使用方法

python - 在 python 中获取 PKCS7 签名者链

java - 组织.apache.spark.SparkException : Task not serializable - Passing RDD

java - 在Java中创建具有多个子节点的XML文件