0

I'm taking over an existing project where I have keys/certs (root and intermediate CA) that were created with openssl. I was told to try to use keytool to generate client certs for client authentication for SSL in Java.

I am not a crypto person so this is all pretty new, but I've used Bouncy Castle in this poc that generates client certs correctly in that a client can authenticate with our service and an SSL connection is established.

public X509Certificate buildEndEntityCert(PublicKey entityKey, PrivateKey caKey, X509Certificate caCert, String clientName)
        throws Exception {
    String name = "CN=Test";
    X509v3CertificateBuilder certBldr = new JcaX509v3CertificateBuilder(
            caCert.getSubjectX500Principal(),
            BigInteger.ONE,
            new Date(System.currentTimeMillis()),
            new Date(System.currentTimeMillis() + VALIDITY_PERIOD),
            new X500Principal(name),
            entityKey);

    JcaX509ExtensionUtils extUtils = new JcaX509ExtensionUtils();

    certBldr.addExtension(Extension.authorityKeyIdentifier, false, extUtils.createAuthorityKeyIdentifier(caCert))
            .addExtension(Extension.subjectKeyIdentifier, false, extUtils.createSubjectKeyIdentifier(entityKey))
            .addExtension(Extension.basicConstraints, false, new BasicConstraints(false))
            .addExtension(Extension.keyUsage, false, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.nonRepudiation))
            .addExtension(Extension.extendedKeyUsage, false, new ExtendedKeyUsage(KeyPurposeId.id_kp_clientAuth));

    ContentSigner signer = new JcaContentSignerBuilder("SHA256withRSA").setProvider("BC").build(caKey);

    return new JcaX509CertificateConverter().setProvider("BC").getCertificate(certBldr.build(signer));
}

I call this method with the intermediateCredential I load on startup for the caKey and caCert parameters. Is there a similar way I can do this with keytool?

If there is not a command or set of commands that I can do to accomplish this, is there an even way to do this? Like create a new truststore, import those certs, and then create new certs from that truststore acting as a CA?

halfer
  • 19,824
  • 17
  • 99
  • 186
Crystal
  • 28,460
  • 62
  • 219
  • 393

1 Answers1

0

In java 7 and 8 (but not earlier) yes the -gencert option of keytool can do this. I haven't yet tested java 9 but I expect it will retain this; new javas almost never drop useful functionality.

A truststore contains only certs, without keys. To sign anything, including a child cert, you need a cert AND key, or depending on your perspective a key AND cert, which means a keystore.

Both java 7 and 8 can use either JKS or PKCS12 format for a keystore (j8 can also use either for truststore, j7 only JKS) but if you currently have the CA key and cert in PEM format, as OpenSSL normally uses, you need to get them into one of the keytool-supported formats. That is a question that has been asked and answered many times already:
How to import an existing x509 certificate and private key in Java keystore to use in SSL?
How do I import the private and public keys (pvk,spc) and certificates (cer) into the keystore?
How can i create keystore from an existing certificate (abc.crt) and abc.key files?
Importing the private-key/public-certificate pair in the Java KeyStore
convert certificate from pem into jks
How to create keystore from cer files
Is it possible to convert an SSL certificate from a .key file to a .pfx?
Convert a CERT/PEM certificate to a PFX certificate
using OpenSSL to create .pfx file
How to create .pfx file from certificate and private key?
How to use .key and .crt file in java that generated by openssl?
How can I set up a letsencrypt SSL certificate and use it in a Spring Boot application?

dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70