2012-05-22 11 views
12

Desidero firmare un file di testo (può essere un file .exe o qualcos'altro in futuro) utilizzando PKCS # 7 e verificare la firma utilizzando Java.Firmare i dati utilizzando PKCS # 7 in JAVA

  1. Cosa devo sapere?
  2. Dove trovo un'API (.jar e documentazione)?
  3. Quali sono i passaggi che devo seguire per firmare i dati e verificare i dati?

Si prega di fornire me snippet di codice, se possibile.

+2

Gentile utente, si prega di rivisitare [questa domanda più anziani] (http://stackoverflow.com/questions/9805385/delete -query-è-non-lavoro-forma-java-application). Ho votato per chiudere l'altra domanda. [Per favore] (http://stackoverflow.com/questions/2377402/how-to-encode-a-value-in-pkcs7-with-java) [do] (http://stackoverflow.com/questions/3166159/ verifica-pkcs7-certificates-in-java) i tuoi compiti prima di fare domande. –

+0

Vuoi che il file exe firmato venga riconosciuto da Windows come firmato. –

risposta

12

Mi sa che sono necessari i seguenti 2 vasetti castello gonfiabile per generare la firma digitale PKCS7:

  • bcprov-jdk15on-147.jar (per JDK 1.5 - JDK 1,7)

  • bcmail- jdk15on-147.jar (per JDK 1.5 - JDK 1,7)

È possibile scaricare i vasetti castello gonfiabile da here.

È necessario configurare il keystore con la coppia di chiavi privata & pubblica. È necessaria solo la chiave privata per generare la firma digitale & la chiave pubblica per verificarlo.

Ecco come ci si PKCS7 contenuti segno (Gestione delle eccezioni omesse per brevità):

import java.io.FileInputStream; 
import java.io.InputStream; 
import java.security.KeyStore; 
import java.security.PrivateKey; 
import java.security.Security; 
import java.security.cert.Certificate; 
import java.security.cert.X509Certificate; 
import java.util.ArrayList; 
import java.util.List; 
import org.bouncycastle.cert.jcajce.JcaCertStore; 
import org.bouncycastle.cms.CMSProcessableByteArray; 
import org.bouncycastle.cms.CMSSignedData; 
import org.bouncycastle.cms.CMSSignedDataGenerator; 
import org.bouncycastle.cms.CMSTypedData; 
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder; 
import org.bouncycastle.jce.provider.BouncyCastleProvider; 
import org.bouncycastle.operator.ContentSigner; 
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder; 
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder; 
import org.bouncycastle.util.Store; 
import org.bouncycastle.util.encoders.Base64; 

public final class PKCS7Signer { 

    private static final String PATH_TO_KEYSTORE = "/path/to/keyStore"; 
    private static final String KEY_ALIAS_IN_KEYSTORE = "My_Private_Key"; 
    private static final String KEYSTORE_PASSWORD = "MyPassword"; 
    private static final String SIGNATUREALGO = "SHA1withRSA"; 

    public PKCS7Signer() { 
    } 

    KeyStore loadKeyStore() throws Exception { 

     KeyStore keystore = KeyStore.getInstance("JKS"); 
     InputStream is = new FileInputStream(PATH_TO_KEYSTORE); 
     keystore.load(is, KEYSTORE_PASSWORD.toCharArray()); 
     return keystore; 
    } 

    CMSSignedDataGenerator setUpProvider(final KeyStore keystore) throws Exception { 

     Security.addProvider(new BouncyCastleProvider()); 

     Certificate[] certchain = (Certificate[]) keystore.getCertificateChain(KEY_ALIAS_IN_KEYSTORE); 

     final List<Certificate> certlist = new ArrayList<Certificate>(); 

     for (int i = 0, length = certchain == null ? 0 : certchain.length; i < length; i++) { 
      certlist.add(certchain[i]); 
     } 

     Store certstore = new JcaCertStore(certlist); 

     Certificate cert = keystore.getCertificate(KEY_ALIAS_IN_KEYSTORE); 

     ContentSigner signer = new JcaContentSignerBuilder(SIGNATUREALGO).setProvider("BC"). 
       build((PrivateKey) (keystore.getKey(KEY_ALIAS_IN_KEYSTORE, KEYSTORE_PASSWORD.toCharArray()))); 

     CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); 

     generator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC"). 
       build()).build(signer, (X509Certificate) cert)); 

     generator.addCertificates(certstore); 

     return generator; 
    } 

    byte[] signPkcs7(final byte[] content, final CMSSignedDataGenerator generator) throws Exception { 

     CMSTypedData cmsdata = new CMSProcessableByteArray(content); 
     CMSSignedData signeddata = generator.generate(cmsdata, true); 
     return signeddata.getEncoded(); 
    } 

    public static void main(String[] args) throws Exception { 

     PKCS7Signer signer = new PKCS7Signer(); 
     KeyStore keyStore = signer.loadKeyStore(); 
     CMSSignedDataGenerator signatureGenerator = signer.setUpProvider(keyStore); 
     String content = "some bytes to be signed"; 
     byte[] signedBytes = signer.signPkcs7(content.getBytes("UTF-8"), signatureGenerator); 
     System.out.println("Signed Encoded Bytes: " + new String(Base64.encode(signedBytes))); 
    } 
} 
+0

Come faccio a generare una chiave pubblica e privata. che tutto l'algoritmo posso usare per firmare. non abbiamo menzionato la lunghezza del bit. puoi fornire qualsiasi riferimento materiale di studio, in modo che io possa capire a2z – user1269042

+0

@ user1269042, Vedere [Crittografia a chiave pubblica] (http://en.wikipedia.org/wiki/Public-key_cryptography) per cominciare. Google in giro per trovare di più. Anche se un po 'datato, [Beginning Cryptography with Java] (http://www.amazon.com/Beginning-Cryptography-Java-David-Hook/dp/0764596330) è un riferimento eccellente. – Zaki

+0

Hai dimenticato di menzionare la necessità di bcpkix-jdk15on-147.jar (ora 148) per le importazioni org.bouncycastle.cms. –

4

PKCS # 7 è noto come CMS ora (Cryptographic Message Syntax), e avrete bisogno delle librerie PKIX di Bouncy Castle per crearne uno. Ha un'ampia documentazione e una mailing list consolidata.

Non fornirò lo snippet di codice, è contro le regole della casa. Mettiti alla prova prima

+0

La versione corrente è chiamata 'bcpkix-jdk15on-147.jar', google it. –

+0

grazie mille per la risposta. Lo analizzerò – user1269042