将证书添加到CMS签名数据

时间:2016-07-26 15:40:02

标签: java openssl bouncycastle pkcs#7

我目前正在使用java Bouncy Castle库来创建CMS签名数据(或PKCS7签名数据)。然而,我似乎无法添加证书(即使证书签名者已正确添加)。

我检查了this question关于正确签名数据的问题,但它没有响应我的SCEP服务器的需求。我使用的代码来自EJBCA,但似乎没有为PKCS7签名数据添加证书。

当我使用openssl cms工具解析签名数据时,我看到"证书"字段是" EMPTY"。此外,当我尝试使用openssl pkcs7 [...] -print_certs打印证书时,我什么都没得到。

以下是我如何使用Bouncy Castle签署我的数据(它的代码很多但足以重现这个问题):

CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
CMSTypedData msg;
List<X509Certificate> certList = new ArrayList<>();
// Make sure the certificate is not null
if (this.certificate != null) {
    certList.add((X509Certificate) this.certificate);
}

/**
* Create the signed CMS message to be contained inside the envelope
* this message does not contain any message, and no signerInfo
**/
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
Collection<JcaX509CertificateHolder> x509CertificateHolder = new ArrayList<>();
try {
    for (X509Certificate certificate : certList) {
        x509CertificateHolder.add(new JcaX509CertificateHolder(certificate));
    }
    CollectionStore<JcaX509CertificateHolder> store = new CollectionStore<>(x509CertificateHolder);
    gen.addCertificates(store);
} catch (Handle all exceptions) {}

上面这段代码通常应该添加证书。我从EJBCA那里拿了这个。

以下是我完成签名数据的方法:

CMSSignedDataGenerator gen1 = new CMSSignedDataGenerator();
// I add ALL of my attributes here
// Once they're added...
Certificate caCert = this.caCertificate;
try {
    String provider = BouncyCastleProvider.PROVIDER_NAME;
    ContentSigner contentSigner = new JcaContentSignerBuilder(signatureAlgorithmName).
            setProvider(provider).
            build(signerKey);
    JcaDigestCalculatorProviderBuilder calculatorProviderBuilder = new JcaDigestCalculatorProviderBuilder().
            setProvider(provider);
    JcaSignerInfoGeneratorBuilder builder = new JcaSignerInfoGeneratorBuilder(calculatorProviderBuilder.build());
    builder.setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(attributes)));
    gen1.addSignerInfoGenerator(builder.build(contentSigner, (X509Certificate) ca));
} catch (Handle all exceptions) {}

// Create the signed data
CMSSignedData sd = gen1.generate(msg, true);
byte[] results = sd.getEncoded();

字节数组结果是DER格式化的PKCS7签名数据......但没有添加证书。

我错过了什么吗?谢谢你的帮助!

1 个答案:

答案 0 :(得分:0)

CMSSignedDataGenerator gen1必须明确添加证书,我不知道。

可以简单地通过以下方式完成:

  • 将证书添加到List的{​​{1}};
  • X509Certificates转换为List的{​​{1}};
  • 将此集合添加到Collection的{​​{1}};
  • 添加商店JcaX509CertificateHolder

代码示例:

CollectionStore

希望这有助于将来的任何人。