2012-05-03 12 views
5

Desidero generare una semplice firma CMS utilizzando bouncycastle. Questo codice funziona!Aggiungere gli attributi firmati/autenticati alla firma CMS utilizzando BouncyCastle

Security.addProvider(new BouncyCastleProvider()); 
    String password = "123456"; 
    KeyStore ks = KeyStore.getInstance("PKCS12"); 
    ks.load(new FileInputStream("c:/cert_123456.p12"), password.toCharArray()); 
    String alias = (String)ks.aliases().nextElement(); 
    PrivateKey key = (PrivateKey)ks.getKey(alias, password.toCharArray()); 
    Certificate[] chain = ks.getCertificateChain(alias); 

    CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); 

    generator.addSigner(key, (X509Certificate)chain[0], CMSSignedDataGenerator.DIGEST_SHA1); 
    ArrayList list = new ArrayList(); 
    for (int i = 0; i < chain.length; i++) { 
     list.add(chain[i]); 
    } 
    CertStore chainStore = CertStore.getInstance("Collection", new CollectionCertStoreParameters(list), "BC"); 
    generator.addCertificatesAndCRLs(chainStore); 
    CMSProcessable content = new CMSProcessableByteArray("test".getBytes()); 
    CMSSignedData signedData = generator.generate(content, false, "BC"); 

    byte[] pk = signedData.getEncoded(); 

Ma, come aggiungere gli attributi firmati?
Desidero rimuovere gli attributi firmati predefiniti e aggiungere l'identificatore della politica della firma.

Gli articoli sono benvenuti.

risposta

7

Prima di tutto sembra che stiate usando i costrutti che sono deprecati nelle ultime versioni di Bouncy Castle. Per aggiungere autenticato/firmato attributes si deve confezionare loro in un AttributeTable attributi Firmata sono aggiunti al firmatario in questo 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); 

poi usarlo in uno dei metodi addSigner. Come ho già detto all'inizio, questo metodo è deprecato e si è incoraggiati a utilizzare Generatori e Generatori di generatori. Ecco un breve esempio:

/* 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(); 

E 'abbastanza ingombrante e probabilmente non funziona ancora (io sono in procinto di scriverlo e incappato in tua domanda mentre la ricerca di un po' di roba), in particolare la parte signingDate, probabilmente deve essere new DERSet(new Time(new Date)) (aggiornamento: funziona con DERUTCTime).

Un po 'di offtopic: non riesco ancora a ottenere la mia testa intorno la differenza tra firmato e autenticato attributi, Castello gonfiabile ha entrambe le classi DefaultAuthenticatedAttributeTableGenerator, DefaultSignedAttributeTableGenerator che funzionano perfettamente con Signers. Sembrano esserci alcune piccole differenze tra i due in merito alla firmaTime, SignedAttributes aggiunge il tempo di firma per impostazione predefinita se non presente. Le RFC menzionano entrambi i tipi di attributi, ma non sono riuscito a trovare nulla di definito.

+0

E come si aggiunge l'attributo "identificatore della politica di firma"? –

+0

Probabilmente manualmente, eredita un CMSAttribute e lo usa. Scopri il codice ASN1 per l'identificatore della politica utilizzando gli strumenti di dump. – soulseekah

+0

Questo è il frammento di codice che ho usato per aggiungere la firma-policy-identifier: Attribute politica = new Attribute ( \t \t \t \t PKCSObjectIdentifiers.id_aa_ets_sigPolicyId, nuova DERSet ( \t \t \t \t \t \t sigPolicy)); –

Problemi correlati