Bouncy Castle 的 CMSSignedData PEM 生成的数据导致解析问题

Bouncy Castle's CMSSignedData PEM produced data causing parsing issues

我正在尝试使用 PKCS#7/CMS 签名对象包装 PKCS#10 请求,因为几乎没有关于如何做到这一点的示例,我已经开始包装 X.509。 我使用了 Bouncy Castel's Example,生成了 CMSSignedData 对象,将其解码为 PEM,并将其存储在文件系统中,并且有效。

问题是我的 CA 以“错误解析 - 遇到错误的 ASN 标签值”拒绝了它,而且 ASN.1 Editor 无法打开文件。

private static void generateCMS(X509Certificate signCert, KeyPair signKP, X509Certificate signedCert) {
  CMSTypedData msg = new CMSProcessableByteArray("Hello world!".getBytes());
        
  CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
  ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA256withRSA")
    .setProvider("BC").build(signKP.getPrivate());

  gen.addCertificate(new X509CertificateHolder(signedCert.getEncoded()));
  gen.addSignerInfoGenerator(
    new JcaSignerInfoGeneratorBuilder(
      new JcaDigestCalculatorProviderBuilder().setProvider("BC").build())
      .build(sha1Signer, signCert));
        
  CMSSignedData sigData = gen.generate(msg, true);
  ContentInfo cmsSignedDataAsASN1 = sigData.toASN1Structure();
  
  JcaPEMWriter writer = new JcaPEMWriter(new FileWriter("test.p7b"));
  writer.writeObject(cmsSignedDataAsASN1);
  writer.close();
}

我注意到一些奇怪的事情,我不确定它是否相关,但是当使用 OpenSSL CMS 模块签署证书时,PEM 编码的 Base 64 总是以字母 "MII" 开头,而我的代码生成 PEM始终以字母 "MIA".

开头

有人可以指出我在这里缺少的内容吗?

我想通了,当 org.bouncycastle.asn1.cms.ContentInfo ASN.1 被写入 OutputStream 时,它使用的是 BER encoding, all I had to do is to get the ASN1Primitive and instruct the decoder to use DER

代码如下:

ASN1Primitive cmsSignedDataAsASN1 = cmsSignedDataAsASN1.toASN1Primitive()
sigData.toASN1Structure().toASN1Primitive()
PemObject pemObject = new PemObject("CMS", 
                      cmsSignedDataAsASN1.getEncoded(ASN1Encoding.DER));
PemWriter pemWriter = new PemWriter(new FileWriter(fileName));
pemWriter.writeObject(pemObject);
pemWriter.close();