Skip to content

Instantly share code, notes, and snippets.

@wsargent
Last active October 23, 2019 18:43
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save wsargent/11023607 to your computer and use it in GitHub Desktop.
Save wsargent/11023607 to your computer and use it in GitHub Desktop.
Create a working(!) client certificate for use with nginx, using only keytool
#!/bin/bash
export PW=`pwgen -Bs 10 1`
echo "$PW" > password
# Create a self signed certificate & private key to create a root certificate authority.
keytool -genkeypair -v \
-alias clientCA \
-keystore client.jks \
-dname "CN=clientCA, OU=Example Org, O=Example Company, L=San Francisco, ST=California, C=US" \
-keypass:env PW \
-storepass:env PW \
-keyalg RSA \
-keysize 2048 \
-ext KeyUsage="keyCertSign" \
-ext BasicConstraints="ca:true" \
-validity 365
# Create another key pair that will act as the client. We want this signed by the client CA.
keytool -genkeypair -v \
-alias client \
-keystore client.jks \
-dname "CN=client, OU=Example Org, O=Example Company, L=San Francisco, ST=California, C=US" \
-keypass:env PW \
-storepass:env PW \
-keyalg RSA \
-keysize 2048
# Create a certificate signing request from the client certificate.
keytool -certreq -v \
-alias client \
-keypass:env PW \
-storepass:env PW \
-keystore client.jks \
-file client.crq
# Make clientCA create a certificate chain saying that client is signed by clientCA.
keytool -gencert -v \
-alias clientCA \
-keypass:env PW \
-storepass:env PW \
-keystore client.jks \
-infile client.crq \
-outfile client.crt \
-ext EKU="clientAuth" \
-rfc
# Export the client-ca certificate from the keystore. This goes to nginx under "ssl_client_certificate"
# and is presented in the CertificateRequest.
keytool -export -v \
-alias clientCA \
-file clientca.crt \
-storepass:env PW \
-keystore client.jks \
-rfc
# Import the signed certificate back into client.jks. This is important, as JSSE won't send a client
# certificate if it can't find one signed by the client-ca presented in the CertificateRequest.
keytool -import -v \
-alias client \
-file client.crt \
-keystore client.jks \
-storetype JKS \
-storepass:env PW
# Export the client CA to pkcs12, so it's safe.
keytool -importkeystore -v \
-srcalias clientCA \
-srckeystore client.jks \
-srcstorepass:env PW \
-destkeystore clientca.p12 \
-deststorepass:env PW \
-deststoretype PKCS12
# Then, strip out the client CA from client.jks.
keytool -delete -v \
-alias clientCA \
-storepass:env PW \
-keystore client.jks
# List out the contents of client.jks just to confirm it.
keytool -list -v \
-keystore client.jks \
-storepass:env PW
echo "PW = $PW"
@brettwooldridge
Copy link

@wsargent Brilliant.

@csc-bnguyen43
Copy link

Thanks, very helpful.

@BobbyTBS
Copy link

Looks great. For us complete noobs, can you tell us where to place these files (or run the script) so nginx can pick them up?

@wsargent
Copy link
Author

wsargent commented Oct 23, 2019

Google for “nginx configuring https servers” on the nginx web site.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment