【问题标题】:Bouncy Castle's CMSSignedData PEM produced data causing parsing issuesBouncy Castle 的 CMSSignedData PEM 生成的数据导致解析问题
【发布时间】:2020-10-27 15:09:24
【问题描述】:

我正在尝试用 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"

有人可以指出我在这里缺少什么吗?

【问题讨论】:

  • 我正在尝试使用 PKCS#7/CMS 签名对象包装 PKCS#10 请求... 为什么?是否有任何 CA 期望这种格式?
  • 是的,Windows CA 在使用注册代理时,用于代表注册流程。这是一个 C# 示例(在第一个答案中):stackoverflow.com/questions/7824408/…
  • 抱歉,我找不到任何关于 CMS 特定子集的规范。你提到的关于“MII”和“MIA”(你真的应该看四个字符的倍数)的一件事让我仔细看看,Bouncycastle 代码生成了一种叫做“构造的、无限长度”的编码,而 OpenSSL输出是“构造的,确定的长度”。我会看看是否有办法让 Bouncycastle 生成该表单。

标签: java bouncycastle pki


【解决方案1】:

我想通了,当org.bouncycastle.asn1.cms.ContentInfo ASN.1 被写入使用BER 编码的OutputStream 时,我所要做的就是获取ASN1Primitive 并指示解码器改用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();

【讨论】:

    猜你喜欢
    • 2012-06-21
    • 1970-01-01
    • 2017-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-05
    • 1970-01-01
    相关资源
    最近更新 更多