Create X509Certificate with BouncyCastle with Java

Here is what I have now to create a digital certificate. And now I can create a digital certificate with a password-protected private key.

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

How to do it self sign?

I have no clues.

How can i do this?

Thanks for any tips.

+6
source share
2 answers

You had all the code needed to create a self-signed certificate. You just had to ensure that your chain contained only one certificate.

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

I would advise you not to throw an AssertionError . This should be used only by Java itself to indicate that the assert incorrect.

+4
source

After we spent the weekend to bring our version to version 143 to 154, I publish the lessons learned, hoping this will save some time for someone in the future.

1) The PKI eXtention API from BC has been moved to its bank. I racked my brains to find PemParser at bcprov-jdk15on-154.jar. The implementation of PemParser is in bcpkix-jdk15on-154.jar. Needless to say, the pkix drum is dependent on the bc kernel.

2) The PEMReader class is not available in the latest version 154. This has been replaced by PemParser.

3) Reading an open certificate from a file on disk:

 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) Reading a secret key with password protection from disk:

 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) When reading a string certificate, this usually happens when we want to perform SSL authentication and transfer the client certificate to the web server to the application server in the Http request header:

 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) Of course, add error handling, exception management, and cleanup to your liking.

+2
source

Source: https://habr.com/ru/post/956051/


All Articles