En primer lugar parece que está utilizando construcciones que están en desuso en las últimas versiones de Bouncy Castle. Para añadir autenticado/firmado attributes hay que empaquetarlos en un AttributeTable atributos firmados se añaden al firmante de este modo:
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);
luego usarlo en uno de los métodos addSigner. Como ya mencioné al principio, este método está en desuso y se le recomienda usar generadores y generadores. He aquí un breve ejemplo:
/* Construct signed attributes */
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);
/* Build the SignerInfo generator builder, that will build the generator... that will generate the SignerInformation... */
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.getEncoded())));
ArrayList<X509CertificateHolder> signingChainHolder = new ArrayList<X509CertificateHolder>();
Iterator i = this.signingChain.iterator();
while (i.hasNext()) {
X509CertificateObject cert = (X509CertificateObject)i.next();
signingChainHolder.add(new X509CertificateHolder(cert.getEncoded()));
}
generator.addCertificates(new JcaCertStore(signingChainHolder));
generator.generate(new CMSAbsentContent(), "BC").getEncoded();
Es bastante voluminosos y, probablemente, no funciona todavía (estoy en el proceso de escribir y topé con su pregunta mientras que la investigación de algunas cosas), especialmente la parte signingDate, probablemente tiene que ser new DERSet(new Time(new Date))
(actualización: funciona con DERUTCTime
).
Un poco offtopic: Todavía no entiendo la diferencia entre los atributos Firmado y Autenticado, Bouncy Castle tiene tanto DefaultAuthenticatedAttributeTableGenerator, clases DefaultSignedAttributeTableGenerator que funcionan perfectamente bien con Signers. Parece que hay algunas diferencias menores entre los dos en cuanto a signingTime, SignedAttributes agrega el tiempo de firma de forma predeterminada si no está presente. Los RFC mencionan ambos tipos de atributos, pero no pude encontrar nada definitivo.
¿Y cómo se agrega el atributo 'signature-policy-identifier'? –
Probablemente de forma manual, herede un CMSAttribute y úselo. Averigüe el código ASN1 para identificador de política utilizando herramientas de volcado. – soulseekah
Este es el fragmento de código I utiliza para añadir la firma-política-identificador: Atributo política = new Atributo ( \t \t \t \t PKCSObjectIdentifiers.id_aa_ets_sigPolicyId, nuevo DERSet ( \t \t \t \t \t \t sigPolicy)); –