11

How to create self-signed root certificate and intermediate CA to be imported in Java keystore?

We will use this for SSL and TLS, and later for Client certificate based CLIENT-AUTH authentication.

Using OpenSSL and KeyTool.

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428

2 Answers2

35

Just a side note for anyone wanting to generate a chain and a number of certificates. Refining @EpicPandaForce's own answer, here's a script that creates a root CA in root-ca/, an intermediate CA in intermediate/ and three certificates to out/, each signed with the intermediate CA.

#!/bin/bash -x

set -e

for C in `echo root-ca intermediate`; do

  mkdir $C
  cd $C
  mkdir certs crl newcerts private
  cd ..

  echo 1000 > $C/serial
  touch $C/index.txt $C/index.txt.attr

  echo '
[ ca ]
default_ca = CA_default
[ CA_default ]
dir            = '$C'                     # Where everything is kept
certs          = $dir/certs               # Where the issued certs are kept
crl_dir        = $dir/crl                 # Where the issued crl are kept
database       = $dir/index.txt           # database index file.
new_certs_dir  = $dir/newcerts            # default place for new certs.
certificate    = $dir/cacert.pem          # The CA certificate
serial         = $dir/serial              # The current serial number
crl            = $dir/crl.pem             # The current CRL
private_key    = $dir/private/ca.key.pem  # The private key
RANDFILE       = $dir/.rnd                # private random number file
nameopt        = default_ca
certopt        = default_ca
policy         = policy_match
default_days   = 365
default_md     = sha256

[ policy_match ]
countryName            = optional
stateOrProvinceName    = optional
organizationName       = optional
organizationalUnitName = optional
commonName             = supplied
emailAddress           = optional

[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name

[req_distinguished_name]

[v3_req]
basicConstraints = CA:TRUE
' > $C/openssl.conf
done

openssl genrsa -out root-ca/private/ca.key 2048
openssl req -config root-ca/openssl.conf -new -x509 -days 3650 -key root-ca/private/ca.key -sha256 -extensions v3_req -out root-ca/certs/ca.crt -subj '/CN=Root-ca'

openssl genrsa -out intermediate/private/intermediate.key 2048
openssl req -config intermediate/openssl.conf -sha256 -new -key intermediate/private/intermediate.key -out intermediate/certs/intermediate.csr -subj '/CN=Interm.'
openssl ca -batch -config root-ca/openssl.conf -keyfile root-ca/private/ca.key -cert root-ca/certs/ca.crt -extensions v3_req -notext -md sha256 -in intermediate/certs/intermediate.csr -out intermediate/certs/intermediate.crt

mkdir out

for I in `seq 1 3` ; do
  openssl req -new -keyout out/$I.key -out out/$I.request -days 365 -nodes -subj "/CN=$I.example.com" -newkey rsa:2048
  openssl ca -batch -config root-ca/openssl.conf -keyfile intermediate/private/intermediate.key -cert intermediate/certs/intermediate.crt -out out/$I.crt -infiles out/$I.request
done
Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
tuomassalo
  • 8,717
  • 6
  • 48
  • 50
14

Based on the following guide, special thanks to Jamie Nguyen for making a guide which made this possible, thank you!

By following the guide on https://jamielinux.com/articles/2013/08/act-as-your-own-certificate-authority/ do the following :

  • Install OpenSSL for Windows: http://slproweb.com/products/Win32OpenSSL.html

  • Add the bin folder to the environment variable PATH

  • Create a directory for the certificates, I will call this cert-test

  • Use the following openssl.cfg data for the [ CA_default ] tag:

this

[ CA_default ]
dir        = .    # Where everything is kept
certs        = $dir/certs                # Where the issued certs are kept
crl_dir    = $dir/crl                # Where the issued crl are kept
database    = $dir/index.txt            # database index file.
new_certs_dir    = $dir/newcerts            # default place for new certs.

certificate    = $dir/cacert.pem                # The CA certificate
serial        = $dir/serial                # The current serial number
crl        = $dir/crl.pem                # The current CRL
private_key    = $dir/private/ca.key.pem       # The private key
RANDFILE    = $dir/.rnd     # private random number file
  • create the directories in cert_test: certs crl newcerts private

  • use following commands to create

Root CA:

openssl genrsa -aes256 -out /etc/pki/CA/private/ca.key.pem 4096

openssl req -new -x509 -days 3650 -key /etc/pki/CA/private/ca.key.pem -sha256 -extensions v3_ca -out /etc/pki/CA/certs/ca.cert.pem
  • create folder intermediate

  • create folders certs crl newcerts private

  • create file index.txt

  • create file serial and write a number into it like 1000

  • execute following

commands:

openssl genrsa -aes256 -out intermediate/private/intermediate.key.pem 4096

openssl req -config intermediate/openssl.cfg -sha256 -new -key intermediate/private/intermediate.key.pem -out intermediate/certs/intermediate.csr.pem

openssl ca -keyfile private/ca.key.pem -cert certs/ca.cert.pem -extensions v3_ca -notext -md sha256 -in intermediate/certs/intermediate.csr.pem -out intermediate/certs/intermediate.cert.pem
  • Create chain file with

cat:

cat intermediate/certs/intermediate.cert.pem certs/ca.cert.pem > intermediate/certs/ca-chain.cert.pem
  • Creating JKS file from chain with

keytool:

keytool -importkeystore -srckeystore ia.p12 -srcstoretype PKCS12 -destkeystore ia.jks

keytool -import -noprompt -trustcacerts -alias test_certificate -file ia.crt -keystore ia.jks -storepass helloworld

keytool -importcert -alias test_cert_ca -keystore "c:\Program Files\Java\jdk1.8.0\jre\lib\security\cacerts" -file ca.crt

keytool -importcert -alias test_cert_ia -keystore "c:\Program Files\Java\jdk1.8.0\jre\lib\security\cacerts" -file ia.crt

And you might have to import the CA cert into the ia.jks.

Puppe
  • 4,995
  • 26
  • 27
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • 1
    I must be missing something. I don't see how to get from the pem files in the "openssl" steps to the "ca.crt" and "ia.crt" files used by "keytool". – mnemotronic Aug 15 '15 at 19:18
  • @mnemotronic unfortunately I wrote this almost a year ago and I don't have the steps at hand, but I think you are unfortunately correct. You need to create a PKCS12 Keystore file from the private key and the certificate (public key). Look up how to create a Keystore from the pem files, I think Keytool can do that if you specify the type of key store and the provider (I remember using it to create BKS Keystore using bouncycastle provider). – EpicPandaForce Aug 15 '15 at 19:24
  • 2
    Why are you adding intermediate certificate to trust store (or whatever `ia.crt` is)? Root certificate should be enough because intermediate is signed by root and this information is stored in all certificates signed by intermediate via extension. Even in the manual you've provided (jammielinux page) it is stated that root certificate should be enough. – wst Aug 21 '16 at 12:47
  • You get an OpenSSL binary with git (along with most of the *nix utilities.....which all makes git a lovable turd). – Bob Oct 26 '18 at 09:16