Russell Bateman
August 2022
This is a script that generates
Here are the gen-certs.sh commands in careful, tabular-parallel form for whatever clarity that provides. Note that "changeit" is used for the key, trust store and password phrase.
You are expected to invoke thus: gen-certs.sh username
#!/bin/sh FQDN="OU=Unit,O=Organization,L=City,S=State,C=US" USERNAME=$1 if [ -z "$USERNAME" ] ; then echo "You must supply username as argument" exit 0 fi echo "1. Generate Tomcat's certificate..." keytool -genkeypair -keyalg RSA -dname "CN=Tomcat,${FQDN}" -alias tomcat -keystore server.jks -storepass changeit -keypass changeit echo "2. Generate the client's certificate..." keytool -genkeypair -keyalg RSA -dname "CN=${USERNAME},${FQDN}" -alias ${USERNAME} -storetype pkcs12 -keystore ${USERNAME}.p12 -storepass changeit -keypass changeit echo "3. Export the client's certificate as storetype PKCS12..." keytool -exportcert -file ${USERNAME}.crt -alias ${USERNAME} -storetype pkcs12 -keystore ${USERNAME}.p12 -storepass changeit echo "4. Import the client's certificate as a CA into Tomcat's keystore..." keytool -importcert -v -trustcacerts -file ${USERNAME}.crt -alias ${USERNAME} -keystore server.jks -storepass changeit -noprompt echo "5. Validate the server's certificate..." keytool -list -v -keystore server.jks -storepass changeit echo "6. Validate the client's certificate..." $ openssl pkcs12 -info -in ${USERNAME}.p12 -password pass:changeit -passout pass:changeit
Additional options to specify include
Observation: the bulk of the output below comes out of keytool -list and openssl x509 -info which validate/display the resulting server.jks and ${USERNAME}.p12 artifacts.
$ gen-certs.sh russ 1. Generate Tomcat's certificate... 2. Generate the client's certificate... 3. Export the client's certificate as storetype PKCS12... Certificate stored in file <russ.crt> 4. Import the client's certificate as a CA into Tomcat's keystore... Certificate was added to keystore [Storing server.jks] 5. Validate the client's certificate... Keystore type: PKCS12 Keystore provider: SUN Your keystore contains 2 entries Alias name: russ Creation date: Aug 9, 2022 Entry type: trustedCertEntry Owner: CN=russ, OU=Unit, O=Organization, L=City, ST=State, C=US Issuer: CN=russ, OU=Unit, O=Organization, L=City, ST=State, C=US Serial number: 8d5bac1 Valid from: Tue Aug 09 05:07:40 MDT 2022 until: Mon Nov 07 04:07:40 MST 2022 Certificate fingerprints: SHA1: AE:38:F3:AB:7C:B2:84:2F:49:18:9D:DB:8C:92:D9:B6:EA:D6:7E:E9 SHA256: E2:FF:7E:A7:69:0C:29:AA:58:74:B4:A9:46:20:9A:86:82:13:38:78:43:2C:0E:C3:46:18:00:45:E4:0B:71:FB Signature algorithm name: SHA256withRSA Subject Public Key Algorithm: 2048-bit RSA key Version: 3 Extensions: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 87 19 C3 80 FA 3A 08 C6 5F 51 26 BF 24 F9 6F 0B .....:.._Q&.$.o. 0010: 08 78 BB 35 .x.5 ] ] ******************************************* ******************************************* Alias name: tomcat Creation date: Aug 9, 2022 Entry type: PrivateKeyEntry Certificate chain length: 1 Certificate[1]: Owner: CN=Tomcat, OU=Unit, O=Organization, L=City, ST=State, C=US Issuer: CN=Tomcat, OU=Unit, O=Organization, L=City, ST=State, C=US Serial number: 68c12ad3 Valid from: Tue Aug 09 05:07:40 MDT 2022 until: Mon Nov 07 04:07:40 MST 2022 Certificate fingerprints: SHA1: 0A:05:58:49:AA:7A:CD:76:AE:8A:E1:8B:20:D6:6B:36:41:31:AD:9A SHA256: 8E:46:90:64:FF:C9:C3:B3:EA:F9:85:3A:13:32:94:4A:0F:47:E4:59:BC:96:EE:F9:46:8A:BB:27:CA:86:62:C5 Signature algorithm name: SHA256withRSA Subject Public Key Algorithm: 2048-bit RSA key Version: 3 Extensions: #1: ObjectId: 2.5.29.14 Criticality=false SubjectKeyIdentifier [ KeyIdentifier [ 0000: 4B 91 10 DE E1 B4 42 B4 BA 02 D3 72 29 7C 63 23 K.....B....r).c# 0010: C5 91 9C C7 .... ] ] ******************************************* ******************************************* 6. Validate the client's certificate... MAC: sha1, Iteration 100000 MAC length: 20, salt length: 20 PKCS7 Data Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256 Bag Attributes friendlyName: russ localKeyID: 54 69 6D 65 20 31 36 36 30 30 34 33 35 33 37 35 38 38 Key Attributes:-----BEGIN ENCRYPTED PRIVATE KEY----- MIIFHDBOBgkqhkiG9w0BBQ0wQTApBgkqhkiG9w0BBQwwHAQIduumSvwdXSwCAggA MAwGCCqGSIb3DQIJBQAwFAYIKoZIhvcNAwcECEVx61Pe+6WCBIIEyO3MeqZyONTi +wUIfFKYeYPTZoH3jjLwYqx51ovmhjVPmxlRCg0f0JYxtlLdsVzZ2KilmSgFLbTg 0jLyjyYBnjPg6ugRhG1saRJqCBjf9jL8jIypgvbfNzMSLh3YSEBf9+6rvnASE6qT dAZJMXJNoQ4P21SIPeFyOZDz+JpecEtNueEGSNl8B+8Pa/g2dS1OE+7AdPPLJyPB Vdo2wFVdmf+rQY/Kpu5t3bAeqcSTAA2ot1msRoWEo34eBZlQn+Q2gQr5KVMZDBNN wwp18tCLRRzrcEJnVF8aRjUzQg5FLE3cE57jGyJYmWvqdFVgR20yEFgr0D3g1WT4 oXkMBsCLcr4Uu3wnsQmyiwBeqJd/jCMAeCpt+KU6Ck/dWHJvVN527qangRfywlpz jPjN5AzaFlSKM4SdSS+6PkVGeMp8uj+VOcvaPuCd5xNTZLKXR1e6yjBfmASoeUre LagSV2fnuLNaODGRs01gP21NqXeeyWtby1QIv7oV+T8hPIdNxKveTxh+WtkbgwCi bHwthk0yPp6INKFZA+yGMZeJPL5+Szue2pxs5lWj5s+8+zuq1N4T3T9oEh+naV+q raXplQw/TEMX4KTagV712cvUZhna5eBDSUegJiUd7P8k/7D03aJRnvxxdfCi/qMx GQ9pfpfETaF9o51rFLqVvNLH5jxtK8hpTKs4yCcD6syX8vitf4zaH+lZTDhxSfT+ UmuwfGyviB3eXX6SXxq4d9EoyzTf8+dS8rieW/xmYV4ojSKNBuQo0b9iObIBSQFi Cmy5I6qstPl9NFhSLQXuG6pRdo63ynKGq9o/2WEfSjh3lVnOHmyTUVEbUlZOfCpq CJN5eFzgyPKT4aJanoAqv51SXt6nITC1bkGycDIC3RlWT6OEQ7nWqNAVJRFglfsL Zz9HYi9xlX9YSGHZy/7u9mS/kzzGNp9du2KxS5jtoR/JXnL+pLMgmwyN5iE/Jrhc KvC5Zg9vZe6vDDLX87qw7SNfp5onxfzwK/m/nuW7H18mpf4CJZ/MMPmEOBBnxtno YxdwLsWiRnXhh9/zhOm/EO/i73txmHA8kXlcKgFyQjb14imMgN9Lbjz2XPcEYmrD AGBratcsxAaDxS7g2BcA1744OtvZ8SamhwMv4ilh+nAeFwYg8ohFicbq2esaXa2X LKmp9hwdR9OeXIVdZieL2RIMvDaaDWcfi0dZGlu4uwkNaHrTb+We/N/x1xYQhv+B +y/k/ITu2/i38PWKkhWU+Q/TVeSqEg6zPScpt4P1LZqZL3qFkLUMBcqn7f+sSdS/ U6VBAPfmfLtsQtSQfnbXzXQ2PrqLFu6Gt63zGlQU8bHS4eUTIBcNkcjAOiAber3S Xo8qFGoX7DmWWccNdUoU2K3a/7+DdQdPMu3InltSuuXnq76Q+/9P6+NGFZZEMH0W bHlpKfSkLDa8XnYrs/BwG/YqrLBkml7cYcJO6Y4tEljKtJwQZXIL+SOBbuXJkUOR h++0tagDTAVdhT6sDNs45AIHf2S4hqKiHdVOYWqgewgDqCrMTuYD0fRPg7afd6ws 2mCpWVnZ0o7rwR0TOAifKUQXvqsOvonHwMH2DwGtIatVNj0fzvo5t5UfjMSYkECl WdTZTSn8aJRk7o5NmwRg5A== -----END ENCRYPTED PRIVATE KEY----- PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 10000, PRF hmacWithSHA256 Certificate bag Bag Attributes friendlyName: russ localKeyID: 54 69 6D 65 20 31 36 36 30 30 34 33 35 33 37 35 38 38 subject=C = US, ST = State, L = City, O = Organization, OU = Unit, CN = russ issuer=C = US, ST = State, L = City, O = Organization, OU = Unit, CN = russ -----BEGIN CERTIFICATE----- MIIDYTCCAkmgAwIBAgIEFvvAdDANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQGEwJV UzEOMAwGA1UECBMFU3RhdGUxDTALBgNVBAcTBENpdHkxFTATBgNVBAoTDE9yZ2Fu aXphdGlvbjENMAsGA1UECxMEVW5pdDENMAsGA1UEAxMEcnVzczAeFw0yMjA4MDkx MTEyMTdaFw0yMjExMDcxMTEyMTdaMGExCzAJBgNVBAYTAlVTMQ4wDAYDVQQIEwVT dGF0ZTENMAsGA1UEBxMEQ2l0eTEVMBMGA1UEChMMT3JnYW5pemF0aW9uMQ0wCwYD VQQLEwRVbml0MQ0wCwYDVQQDEwRydXNzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A MIIBCgKCAQEAo5USeJobr6cXKe3RgaoCUzrHofgj8bv8hmI2b+aW49yrlkmVQQyT eKRVlPsCroI4JKpASwDnt6AI5T56lInXCC9ADDTcpudKvgaJF7cRiRu5zOWWDZgf HWKi20pTn6HeMNsH7xsm3KmYubw6BjaWZ/wbE2VvRHgvuhs1wo6uUnU2zxlPqJHj zSqSlBjo+s4XR9hcEVH9Idr7gZwhWvkjQi0PF7wZCbogMHKuRLSbiwnEPeNJ80fk tPMIzEAFBRUZVOFIhfWWsEc4SqrTEKh3B4mQ7Upg+y0VdaX5MN1vOCbGHZMlJtfd lVw/JcEs0mDUevBD8Ris3A2r2DuaBHKFowIDAQABoyEwHzAdBgNVHQ4EFgQUH5FQ n8uQEgePl801xz55grBlBlgwDQYJKoZIhvcNAQELBQADggEBAIdn46vSFPd2q5SC p0j8AAA7+R3gar7XLdC4e+0qygmlzyZImExzSoNdRhpJlicpNjSVzpeFfkrRNnz6 xEyHSsRmbvx38cUIHv9yMbGDZA0YG1nLvLet3weT0zmCuFgbtD6XQIEo4MRNLo2X pYkP4y5ZOO/bXxfNNX83Q/9VgZ8Y2QMxRagFozZ3i05i9AccXMj7FWRFlexpFxcE Ft/U16CUICQRaf6zreb+Szvy5NrRv1wA+G5AUpHIydJOOb8djCZlLipGu6Yv2xxy hfV70ybo+SJfzuwCO1S+064xxXLx2dWPhsaDE28iRDidqqYde5SdcAzZMfFj46I/ J9KFcCE= -----END CERTIFICATE----- $ ll -rw-rw-r-- 1 russ russ 869 Aug 9 05:07 russ.crt -rw-rw-r-- 1 russ russ 2693 Aug 9 05:07 russ.p12 -rw-rw-r-- 1 russ russ 3673 Aug 9 05:07 server.jks
Tomcat's keystore artifact is put somewhere in the filesystem where Tomcat can access it, e.g.: ${CATALINA_BASE}/certificates. On my server, this ends up being /opt/tomcat/certificates, which is a custom subdirectory I'm adding to Tomcat.
Tomcat is informed of this keystore by adding the following paragraph to ${CATALINA_BASE}/conf/server.xml just after (or in place of if you wish to disallow non-TLS access) <Connector port="8080" ... /> in that file. I'm doing this in Tomcat 9:
<Connector port="8443" protocol="HTTP/1.1" connectionTimeout="20000" scheme="https" secure="true" SSLEnabled="true"> <SSLHostConfig> <Certificate certificateKeyAlias="tomcat" certificateKeystoreFile="certificates/server.jks" certificateKeystorePassword="changeit" /> </SSLHostConfig> </Connector>
The username certificate, here russ.p12, can be used to authenticate the client by importing it into the browser or other client software. The reason this works is because of step 4 where the client's certificate is imported into the server's keystore. This is to force Tomcat to trust the client.
Authenticating the client is not rigidly required nor always something you want to do in your microservice architecture.
Sometimes, you want the client to vet the server to ensure that client data isn't wrongly sent to some server. In this case, you want to set the server's certificate up in a trusted store such that, if missing, the software the client uses will refuse to work. And example of this would be Apache NiFi's InvokeHTTP processor.
To accomplish this, you would...