2016-07-26 94 views
1

我目前使用java Bouncy Castle庫來創建CMS簽名數據(或PKCS7簽名數據)。我似乎仍然堅持添加證書(即使證書籤名者已正確添加)。將證書添加到CMS簽名數據

我檢查了this question有關正確數據簽名,但它並沒有迴應我的SCEP服務器的需求。我使用的代碼來自EJBCA,但似乎沒有將證書添加到PKCS7簽名的數據。

當我解析與openssl cms工具簽名的數據,我看到「證書」字段是「空」。此外,當我嘗試打印openssl pkcs7 [...] -print_certs的證書時,我什麼都沒有收到。

這裏是我籤我用充氣城堡的數據(這是一個很大的代碼,但足以重現該問題):

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(); 

的字節數組結果是格式化的PKCS7簽名數據的DER ...但不添加證書。

我錯過了什麼嗎?感謝您的幫助!

回答

0

CMSSignedDataGenerator gen1有明確添加證書,這點我是不知道的。

它可以簡單地這樣做:

  • 添加證書X509CertificatesList;
  • 轉換該ListJcaX509CertificateHolderCollection;
  • 將此集合添加到JcaX509CertificateHolderCollectionStore;
  • 添加商店CMSSignedDataGenerator

代碼示例:

CMSSignedDataGenerator gen1 = new CMSSignedDataGenerator(); 
List<X509Certificate> certificates = new ArrayList<>(); 

// I chose to add the CA certificate 
certificates.add((X509Certificate) this.caCertificate); 

// In this case, this is a certificate that I need to add 
if (this.certificate != null) 
    certificates.add((X509Certificate) this.certificate); 

// This is the recipient certificate 
if (this.recipientCert != null) 
    certificates.add((X509Certificate) this.recipientCert); 
Collection<JcaX509CertificateHolder> x509CertificateHolder = new ArrayList<>(); 

// Of course, we need to handle the exceptions... 
for (X509Certificate certificate : certificates) { 
    x509CertificateHolder.add(new JcaX509CertificateHolder(certificate)); 
} 
CollectionStore<JcaX509CertificateHolder> store = new CollectionStore<>(x509CertificateHolder); 

// The final stage. 
gen1.addCertificates(store); 

希望這有助於在未來的人。

+0

嗨,我試過上述解決方案,但不幸的是,證書不存在於最終的數字簽名中。您是否驗證了數字簽名中是否存在證書? –

+0

你好,抱歉,遲交的回覆。我不幸無法再訪問源代碼,但我仍然可以嘗試幫助你。我記得在生成數字簽名('CSMSignedDataGenerator')後獲得證書('this.certificate')。我沒有添加CA,因此它不存在。您是否確保將證書添加到「證書」列表中? –