Po pierwsze wydaje się, że używasz konstruktów, które są przestarzałe w najnowszych wersjach Bouncy Castle. Aby dodać uwierzytelnione/podpisana attributes trzeba je pakietu w AttributeTable Podpisano atrybutami są dodawane do podpisującego tak:
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);
następnie używać go w jednej z metod addSigner. Jak już wspomniałem na początku, ta metoda jest przestarzała i zachęcamy do korzystania z Generatorów i Generatorów Generatorów. Oto krótki przykład:
/* 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();
To dość nieporęczne i chyba jeszcze nie działa (jestem w trakcie pisania i natknęliśmy się na swoje pytanie podczas badania kilka rzeczy), w szczególności część signingDate, to prawdopodobnie musi być new DERSet(new Time(new Date))
(aktualizacja: działa z DERUTCTime
).
Trochę offtopic: wciąż nie mogę zrozumieć różnicy między atrybutami Signed i Authenticated, Bouncy Castle ma klasy DefaultAuthenticatedAttributeTableGenerator, DefaultSignedAttributeTableGenerator, które doskonale działają z Signers. Wydaje się, że pomiędzy tymi dwoma elementami występują niewielkie różnice pod względem czasu logowania, opcja Podpisane atrybuty domyślnie dodaje wartość czasu do podpisu, jeśli nie jest obecna. W dokumentach RFC wymieniono oba typy atrybutów, ale nie mogłem znaleźć niczego konkretnego.
A jak dodać atrybut "identyfikator polityki podpisu"? –
Prawdopodobnie ręcznie, dziedziczy CMSAttribute i używa go. Znajdź kod ASN1 dla identyfikatora polityki za pomocą narzędzi dump. – soulseekah
Jest to fragment kodu użyłem, aby dodać podpis-policy-identyfikator: Attribute polityki = nowy atrybut ( \t \t \t \t PKCSObjectIdentifiers.id_aa_ets_sigPolicyId, nowy DERSet ( \t \t \t \t \t \t sigPolicy)); –