首先,您似乎正在使用最新版本的Bouncy
Castle中不推荐使用的构造。要添加经过身份验证/签名的属性,您必须将它们打包到AttributeTable中,将签名的属性添加到签名者,如下所示:
ASN1EncodableVector signedAttributes = new ASN1EncodableVector();signedAttributes.add(new Attribute(CMSAttributes.contentType, new DERSet(new ASN1ObjectIdentifier("1.2.840.113549.1.7.1"))));signedAttributes.add(new Attribute(CMSAttributes.messageDigest, new DERSet(new DEROctetString(digestBytes))));signedAttributes.add(new Attribute(CMSAttributes.signingTime, new DERSet(new DERUTCTime(signingDate))));AttributeTable signedAttributesTable = new AttributeTable(signedAttributes);然后在addSigner方法之一中使用它。正如我在开始时已经提到的那样,不建议使用此方法,建议您使用Generators和Generator
Builders。这是一个简短的示例:
ASN1EncodableVector signedAttributes = new ASN1EncodableVector(); signedAttributes.add(new Attribute(CMSAttributes.contentType, new DERSet(new ASN1ObjectIdentifier("1.2.840.113549.1.7.1")))); signedAttributes.add(new Attribute(CMSAttributes.messageDigest, new DERSet(new DEROctetString(digestBytes)))); signedAttributes.add(new Attribute(CMSAttributes.signingTime, new DERSet(new DERUTCTime(signingDate)))); AttributeTable signedAttributesTable = new AttributeTable(signedAttributes); signedAttributesTable.toASN1EncodableVector(); DefaultSignedAttributeTableGenerator signedAttributeGenerator = new DefaultSignedAttributeTableGenerator(signedAttributesTable); SignerInfoGeneratorBuilder signerInfoBuilder = new SignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()); signerInfoBuilder.setSignedAttributeGenerator(signedAttributeGenerator); CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); JcaContentSignerBuilder contentSigner = new JcaContentSignerBuilder("SHA1withRSA"); contentSigner.setProvider("BC"); generator.addSignerInfoGenerator(signerInfoBuilder.build(contentSigner.build(this.signingKey), new X509CertificateHolder(this.signingCert.getEnpred()))); ArrayList<X509CertificateHolder> signingChainHolder = new ArrayList<X509CertificateHolder>(); Iterator i = this.signingChain.iterator(); while (i.hasNext()) { X509CertificateObject cert = (X509CertificateObject)i.next(); signingChainHolder.add(new X509CertificateHolder(cert.getEnpred())); } generator.addCertificates(new JcaCertStore(signingChainHolder)); generator.generate(new CMSAbsentContent(), "BC").getEnpred();它非常笨重,可能还无法正常工作(我正在编写过程中,在研究某些东西时偶然发现了您的问题),尤其是signingDate部分,它可能必须是
newDERSet(new Time(new Date))(update:它可以使用
DERUTCTime)。
有点离题:我仍然无法理解Signed和Authenticated属性之间的区别,Bouncy
Castle拥有DefaultAuthenticatedAttributeTableGenerator和DefaultSignedAttributeTableGenerator类,它们与Signers完美配合。两者之间在signingTime方面似乎有一些细微的差异,如果不存在,SignedAttributes默认会添加signingTime。RFC提到了两种属性类型,但是我找不到任何确定的东西。



