2013-10-16 14 views
6

Questo è ciò che ho ora per generare un certificato digitale. E ora sono in grado di generare un certificato digitale con password protetta per chiave privata.Generazione di X509Certificate con BouncyCastle con Java

public static void main(String[] args) throws Exception { 
    Security.addProvider(new BouncyCastleProvider()); 
    testKeyStore(); 
} 

public static void testKeyStore() throws Exception { 
    try { 
     String storeName = "d://suresh_test.cer"; 
     java.security.KeyPairGenerator keyPairGenerator = KeyPairGenerator 
       .getInstance("RSA"); 
     keyPairGenerator.initialize(2048); 
     KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
     PublicKey publicKey = keyPair.getPublic(); 
     PrivateKey privateKey = keyPair.getPrivate(); 
     X509Certificate trustCert = createCertificate("CN=CA", "CN=CA", 
       publicKey, privateKey); 
     java.security.cert.Certificate[] outChain = { 
       createCertificate("CN=Client", "CN=CA", publicKey, 
         privateKey), trustCert }; 
     KeyStore outStore = KeyStore.getInstance("PKCS12"); 
     outStore.load(null, "suresh_".toCharArray()); 
     outStore.setKeyEntry("mykey", privateKey, "suresh_".toCharArray(), 
       outChain); 
     OutputStream outputStream = new FileOutputStream(storeName); 
     outStore.store(outputStream, "suresh_".toCharArray()); 
     outputStream.flush(); 
     outputStream.close(); 

     KeyStore inStore = KeyStore.getInstance("PKCS12"); 
     inStore.load(new FileInputStream(storeName), 
       "suresh_".toCharArray()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     throw new AssertionError(e.getMessage()); 
    } 
} 

private static X509Certificate createCertificate(String dn, String issuer, 
     PublicKey publicKey, PrivateKey privateKey) throws Exception { 
    X509V3CertificateGenerator certGenerator = new X509V3CertificateGenerator(); 
    certGenerator.setSerialNumber(BigInteger.valueOf(Math.abs(new Random() 
      .nextLong()))); 
    certGenerator.setIssuerDN(new X509Name(dn)); 
    certGenerator.setSubjectDN(new X509Name(dn)); 
    certGenerator.setIssuerDN(new X509Name(issuer)); // Set issuer! 
    certGenerator.setNotBefore(Calendar.getInstance().getTime()); 
    certGenerator.setNotAfter(Calendar.getInstance().getTime()); 
    certGenerator.setPublicKey(publicKey); 
    certGenerator.setSignatureAlgorithm("SHA1WithRSAEncryption"); 
    X509Certificate certificate = (X509Certificate) certGenerator.generate(
      privateKey, "BC"); 
    return certificate; 
} 

Come fare Autodidatta?

Non ho indizi.

Come posso procedere?

Grazie per eventuali suggerimenti.

+1

La tua domanda non spiega cosa hai fatto per provare a risolvere il problema; attualmente si legge come una richiesta di codice. Condividi la tua tentata implementazione e spiega come non soddisfa le tue esigenze. –

+0

@DuncanJones Bene, ho generato il certificato. Ma non so come firmarlo usando l'API bouncy castle, non ho trovato nulla nel loro sito web. Grazie per l'aiuto. –

risposta

4

Hai avuto tutto il codice necessario per produrre un certificato autofirmato. Dovevi solo assicurarti che la catena contenesse un solo certificato.

public static void testKeyStore() throws Exception { 
    try { 
    String storeName = "path/to/store"; 
    java.security.KeyPairGenerator keyPairGenerator = KeyPairGenerator 
     .getInstance("RSA"); 
    keyPairGenerator.initialize(2048); 
    KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
    PublicKey publicKey = keyPair.getPublic(); 
    PrivateKey privateKey = keyPair.getPrivate(); 
    X509Certificate selfCert = createCertificate("CN=Client", "CN=Client", 
     publicKey, privateKey); 

    // Note: if you just want to store this certificate then write the 
    // contents of selfCert.getEncoded() to file 

    java.security.cert.Certificate[] outChain = { selfCert }; 
    KeyStore outStore = KeyStore.getInstance("PKCS12"); 
    outStore.load(null, PASSWORD.toCharArray()); 
    outStore.setKeyEntry("mykey", privateKey, PASSWORD.toCharArray(), 
     outChain); 
    OutputStream outputStream = new FileOutputStream(storeName); 
    outStore.store(outputStream, PASSWORD.toCharArray()); 
    outputStream.flush(); 
    outputStream.close(); 

    KeyStore inStore = KeyStore.getInstance("PKCS12"); 
    inStore.load(new FileInputStream(storeName), PASSWORD.toCharArray()); 
    } catch (Exception e) { 
    e.printStackTrace(); 
    throw new AssertionError(e.getMessage()); 
    } 
} 

vi consiglio di non buttare un AssertionError. Questo dovrebbe essere usato solo da Java stesso per indicare che un'istruzione assert è falsa.

+1

Grazie Jones, un piccolo dubbio. 'outStore.load (null, PASSWORD.toCharArray());' e 'outStore.setKeyEntry (" mykey ", privateKey, PASSWORD.toCharArray(), outChain);" perché le due password utilizzate? è necessario per il file keystore? Possono entrambe le password diverse? –

+0

@ sᴜʀᴇsʜᴀᴛᴛᴀ In primo luogo, quelle righe sono nel mio esempio di codice perché erano nel codice originale. Controlla la documentazione di 'KeyStore' per capirne il significato. –

+0

Sì, sto facendo lo stesso. :) Grazie per l'aiuto. Se hai tempo per favore guarda qui. http://stackoverflow.com/questions/19421571/providing-key-usage-to-x509certificate-generated-with-with-java-bouncycastle –

2

Dopo aver trascorso il fine settimana a portare la nostra versione BC da 143 a 154, sto postando le nozioni apprese, sperando che risparmi un po 'di tempo per qualcuno in futuro.

1) L'API di eKtention PKI di BC è stata spostata nel proprio jar. Mi stavo rompendo la testa per trovare PemParser in bcprov-jdk15on-154.jar. L'implementazione per PemParser è in bcpkix-jdk15on-154.jar. Inutile dire che il barattolo di pkix dipende dal barattolo principale di bc.

2) La classe PEMReader non è disponibile nell'ultima versione 154. Questo è stato sostituito da PemParser.

3) La lettura di un certificato pubblico da file su disco:

Security.addProvider(new BouncyCastleProvider()); 
File file = new File("c:/mycert.crt"); 
X509Certificate cert = null; 
PEMParser pemParser = new PEMParser(new FileReader(file)); 
Object object = pemParser.readObject(); 
if (object instanceof X509CertificateHolder) { 
    X509CertificateHolder holder = (X509CertificateHolder)object; 
    cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder); 
} 
if (cert == null) { 
    throw new Exception("mycert.crt" + " doesn't contain X509Certificate!"); 
} 
return cert; 
//If you need publicKey use cert.getPublicKey() method. 

4) La lettura di un protetto da password chiave privata dal disco:

Security.addProvider(new BouncyCastleProvider()); 
KeyPair keyPair = null; 
File file = new File("c:/myprivate.key"); 
PEMParser pemParser = new PEMParser(new FileReader(file)); 
Object object = pemParser.readObject(); 
if (object instanceof PEMEncryptedKeyPair) { 
    JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); 
    PEMEncryptedKeyPair ckp = (PEMEncryptedKeyPair) object; 
    PEMDecryptorProvider decProv = 
      new JcePEMDecryptorProviderBuilder().build("strongpasswordfor_myprivate.key".toCharArray()); 
    keyPair = converter.getKeyPair(ckp.decryptKeyPair(decProv)); 
} 
return keyPair; 
//Once we have the keypair, we can get keyPair.getPrivate() [PrivateKey.class] 
//or keyPair.getPublic() [PublicKey.class] 

5) Lettura di un certificato di corda a base, questo è in genere il caso in cui si desidera eseguire l'autenticazione reciproca SSL e il server Web inoltra il certificato client al server delle applicazioni nell'intestazione della richiesta HTTP:

Security.addProvider(new BouncyCastleProvider()); 
X509Certificate cert = null; 
    String myClientCert = "-----BEGIN CERTIFICATE----- CERTCONTENTS -----END CERTIFICATE-----" 
    String cert1 = myClientCert.replaceAll("-----BEGIN CERTIFICATE-----", "").replaceAll("-----END CERTIFICATE-----", "").replaceAll(" ", System.lineSeparator()); 
    int ind = cert1.lastIndexOf(System.lineSeparator()); 
    cert1 = new StringBuilder(cert1).replace(ind, ind + System.lineSeparator().length(), "").toString(); 
    cert1 = BEGIN_CERT + cert1 + END_CERT; 
    PEMParser pemParser = new PEMParser(new StringReader(cert1)); 
    Object object = pemParser.readObject(); 
    if (object instanceof X509CertificateHolder) { 
     X509CertificateHolder holder = (X509CertificateHolder)object; 
     cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder); 
    } 
    return cert; 

6) Inutile dire che aggiungere la gestione degli errori, la gestione delle eccezioni & pulizia a vostro gusto.

Problemi correlati