2013-10-16 24 views
6

Oto, co mam teraz, aby wygenerować certyfikat cyfrowy. Teraz mogę wygenerować certyfikat cyfrowy z hasłem chronionym kluczem prywatnym.Generowanie certyfikatu X509 za pomocą programu BouncyCastle z językiem 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; 
} 

Jak zrobić to samodzielnie znak?

Nie mam wskazówek.

Jak mogę to zrobić?

Dzięki za wszelkie wskazówki.

+1

Twoje pytanie nie wyjaśnia, co zrobiłeś, aby spróbować rozwiązać problem; obecnie czyta się jak prośbę o kod. Podziel się swoją próbą wdrożenia i wyjaśnij, w jaki sposób nie spełnia Twoich wymagań. –

+0

@DuncanJones Cóż, wygenerowałem certyfikat. Ale nie wiesz, jak to podpisać, korzystając z API Skoczni Zamkowej, nie znalazłeś żadnej rzeczy na swojej stronie internetowej. Dzięki za pomoc. –

Odpowiedz

4

Posiadałeś cały kod potrzebny do stworzenia samopodpisanego certyfikatu. Musisz tylko upewnić się, że twój łańcuch zawiera tylko jeden certyfikat.

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()); 
    } 
} 

Radzę nie rzucać AssertionError. To powinno być używane tylko przez Javę, aby wskazać, że instrukcja assert jest fałszywa.

+1

Dziękuję Jones, jedna drobna wątpliwość. 'outStore.load (null, PASSWORD.toCharArray());' i 'outStore.setKeyEntry (" mykey ", privateKey, PASSWORD.toCharArray(), outChain);' dlaczego oba hasła zostały użyte? czy jest to konieczne w przypadku pliku kluczy? Czy oba hasła mogą się różnić? –

+0

@ sᴜʀᴇsʜᴀᴛᴛᴀ Przede wszystkim te linie są w moim przykładzie kodu, ponieważ były w oryginalnym kodzie. Sprawdź dokumentację 'KeyStore', aby zrozumieć ich znaczenie. –

+0

Tak, robię to samo. :) Dzięki za pomoc. Jeśli masz czas, zajrzyj do tego. http://stackoverflow.com/questions/19421571/providing-key-usage-to-x509certificate-generated-with-jaith-java-bouncycastle –

2

Po spędzeniu weekendu, aby przenieść naszą wersję BC z 143 do 154, publikuję wyuczone lekcje, mając nadzieję, że zaoszczędzi to trochę czasu komuś w przyszłości.

1) Interfejs API PKI eXtention z BC został przeniesiony do własnego słoika. Łamałem głowę, aby znaleźć PemParser w bcprov-jdk15on-154.jar. Implementacja PemParser znajduje się w bcpkix-jdk15on-154.jar. Nie trzeba dodawać, że słoik pkix zależy od rdzenia bc słoika.

2) Klasa PEMReader nie jest dostępna w najnowszej wersji 154. Zostało to zastąpione przez PemParser.

3) Czytanie certyfikat publiczny z pliku na dysku:

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) Czytanie hasło chroniony klucz prywatny z dysku:

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) Odczyt certyfikat jest ciąg oparty jest to Zazwyczaj ma to miejsce, gdy chcemy wykonać uwierzytelnianie SSL i przekazujemy serwerowi internetowym certyfikat klienta do serwera aplikacji w nagłówku żądania 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) Nie trzeba dodawać, dodawać obsługę błędów, zarządzanie wyjątkami & porządek według upodobań.