7

I want to create with java apis a keystore "PCKS12" from an existing crt file. is it possible? if yes how to make that?

EDIT

1/ openssl req -newkey rsa:2048 -nodes -keyout keyFile.key -x509 -days 3650 -out certFile.crt
2/ openssl pkcs12 -export -in certFile.crt -inkey keyFile.key -out tmp.p12 -name alias
3/ keytool -importkeystore -srckeystore tmp.p12 -srcstoretype PKCS12 -srcstorepass password -destkeystore keyStoreFile.jks -deststoretype JKS -deststorepass password -destkeypass password -alias alias

How to make step 2 and 3 programatically ?

1
  • Assuming the crt file only contains a public key, it wouldn't do you much good. A p12 file is typically a public/private key pair. Commented Aug 3, 2017 at 15:37

1 Answer 1

14

You can create a PKCS #12 keystore containing a root CA with Java's keytool:

keytool -importcert -trustcacerts -keystore keystore.p12 -storetype pkcs12 \ -alias root -file root.crt 

You will be prompted for a password that will be used to protect the integrity of the key store, so that no one can modify your trust anchors without detection. You can specify the password with another option, but that is likely to leave a record of the password on the system.

Here, -trustcacerts means that you trust the certificate that you are importing as a certifying authority. If you leave this out, the certificate will be displayed, and you will be prompted to review and accept it.

The alias "root" is effectively the nickname of the certificate in your store, and it can be anything that helps you identify this certificate later.

And, of course, the file "root.crt" is the CA certificate you want to import.


Programatically:

static void createTrustStore(Path certificate, Path keystore, char[] password) throws IOException, GeneralSecurityException { CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate root; try (InputStream is = Files.newInputStream(certificate)) { root = cf.generateCertificate(is); } KeyStore pkcs12 = KeyStore.getInstance("PKCS12"); pkcs12.load(null, null); pkcs12.setCertificateEntry("root", root); try (OutputStream os = Files.newOutputStream(keystore, StandardOpenOption.CREATE_NEW)) { pkcs12.store(os, password); } } private static final byte[] HEADER = "-----".getBytes(StandardCharsets.US_ASCII); static void createIdentityStore(Path certificate, Path key, Path keystore, char[] password) throws IOException, GeneralSecurityException { byte[] pkcs8 = decode(Files.readAllBytes(key)); KeyFactory kf = KeyFactory.getInstance("RSA"); PrivateKey pvt = kf.generatePrivate(new PKCS8EncodedKeySpec(pkcs8)); CertificateFactory cf = CertificateFactory.getInstance("X.509"); Certificate pub; try (InputStream is = Files.newInputStream(certificate)) { pub = cf.generateCertificate(is); } KeyStore pkcs12 = KeyStore.getInstance("PKCS12"); pkcs12.load(null, null); pkcs12.setKeyEntry("identity", pvt, password, new Certificate[] { pub }); try (OutputStream s = Files.newOutputStream(keystore, StandardOpenOption.CREATE_NEW)) { pkcs12.store(s, password); } } private static byte[] decode(byte[] raw) { if (!Arrays.equals(Arrays.copyOfRange(raw, 0, HEADER.length), HEADER)) return raw; CharBuffer pem = StandardCharsets.US_ASCII.decode(ByteBuffer.wrap(raw)); String[] lines = Pattern.compile("\\R").split(pem); String[] body = Arrays.copyOfRange(lines, 1, lines.length - 1); return Base64.getDecoder().decode(String.join("", body)); } 
Sign up to request clarification or add additional context in comments.

3 Comments

I want to create it programatically
can you see my EDIT please because as Input I have a .crt and a .key files
I do have a ca_bundle.crt, a certificate.crt and a private.key. ZeroSSL provided more than just a single crt file. What to do?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.