Working with Certs and the Truststore
Describes how to provide a truststore with a valid server certificate, including how to view and locate certs, as well as how to create and validate a truststore for certs.
When you use an external AD/LDAP server, Keycloak verifies the server certificate. If the certificate is not signed by a commonly known certificate authority (CA), you must provide a truststore with the information required to verify that the server certificate is valid.
Note the following guidelines and conditions related to certs and the truststore:
- A truststore is needed for StartTLS or LDAPS connections. Different applications with potentially different default trusted-certificate stores may need to verify the connection, so the means to verify the LDAP server’s certificate must be explicitly provided.
- A truststore contains the certs required to finish the signing chain – from the issuing cert mentioned in the cert that the server presents to the trusted self-signed cert. In the case of a self-signed server cert, the chain is the server cert itself.
- Any truststore that you provide must contain all of the necessary certs. The truststore must be a chain of certs signed by certs that terminate in a self-signed cert.
Locating the Certs to put in the Truststore
If you do not know which certs need to go into the truststore (possibly due to IT
protocols), use openssl
to probe the server to see which certs are being
presented by the AD/LDAP server.
myserver-cert1.pem,
myserver-cert2.pem
, and so on. These are the certs presented by the server. The
first one is the server cert, followed by any intermediate certs. - LDAPS server
- The following command probes an LDAPS server running at
myserver.com
onport 636
:openssl s_client -showcerts -verify 10 -connect myserver.com:636 < \ /dev/null | \ awk '/BEGIN/,/END/{if(/BEGIN/) {a++}; out="myserver-cert"a".pem"; print >out}'
- StartTLS server
- The following command probes an StartTLS server running at
myserver.com
onport 389
:openssl s_client -showcerts -verify 10 -connect myserver.com:389 -starttls ldap < \ /dev/null | \ awk '/BEGIN/,/END/{if(/BEGIN/) {a++}; out="myserver-cert"a".pem"; print >out}'
- Getting the Issuer and Subject from a cert file
- To get the Issuer and Subject from a cert file, run the following
command:
openssl x509 -in myserver-cert1.pem -text | grep '\(Issuer\|Subject\)'
TIP- If there is only one cert and it refers to itself as Issuer, that means it is a self-signed server cert, and that server cert needs to go into the truststore.
- If there is a list of Issuers certs, there is typically one Issuer that does not have a match among the Subjects. That missing Issuer cert is the next link in the trust chain. You will need to get that cert either by way of the CA, your IT department, or whoever configured and runs the server. Often the missing Issuer is a custom root cert, in which case you only have one cert to put in your truststore.
- If the missing Issuer is not a root cert and is actually an intermediate cert, you will need to get the intermediate cert and also get the cert that the intermediate cert is signed by and continue this process until you get to the root (self-signed) cert.
Creating a Truststore
Build the truststore with the Java keytool
utility by performing a series
of cert imports.
- Keytool can import X.509 v1, v2, and v3 certificates, and PKCS#7 formatted certificate chains consisting of certificates of that type.
- The data to be imported must be provided either in binary encoding format or in printable encoding format (also known as Base64 encoding) as defined by the Internet RFC 1421 standard. In the latter case, the encoding must be bounded at the beginning by a string that starts with "-----BEGIN" and bounded at the end by a string that starts with "-----END"."
- Importing a truststore and setting the password
- Alias values in the commands are used for readability when dumping the truststore.
You can use any alias you choose.
The first import creates the truststore. During the first import, you set the password for the truststore. Subsequent imports will ask for this password.
To import a self-signed server cert from theservercert.pem
file, run the following command:NOTEThis is the only command you have to run for a self-signed certificate.
When asked if you want to trust it, respond withkeytool -importcert -alias selfsigned \ -file servercert.pem -keystore truststore.jks
yes
. - Importing a custom root cert and intermediate certs
- To import a custom root cert and intermediate certs, start by running the following command to import the custom root cert (ATTENTIONIf you follow the instructions to import down the trust chain, you should not be asked whether any of the intermediate certs should be trusted because keytool should be aware of what cert they were signed by. If you get that question when importing an intermediate cert, you may have missed a link in the chain or you are importing in the wrong order.
root.pem
in this example):
When asked if you want to trust it, respond withkeytool -importcert -alias root \ -file root.pem -keystore truststore.jks
yes
. - Importing intermediate certs
- If you have intermediate certs to import, start with the one closest to the root,
and work down the signing chain toward the server cert. If your first intermediate
cert was signed by a default trusted cert, run the following command to import it
(example filename
intermediate.pem
):keytool -importcert -trustcacerts -alias intermediate \ -file intermediate.pem -keystore truststore.jks
For any intermediate cert signed by something previously imported into your truststore, run the following command to import it without the trustcacerts argument:keytool -importcert -alias intermediate \ -file intermediate.pem -keystore truststore.jks
Validating a Truststore
Run the command appropriate for your server type and then press enter to kill the connection. If the validation is successful, the system returns the following message:
Verify return code: 0 (ok)
If the truststore is not correct, the system returns the following message:
Verify return code: 20 (unable to get local issuer certificate)
- LDAPS
- To validate a truststore, run the following command:NOTEThe following example validates that a truststore named
truststore.jks
with passwordmypass
works for an LDAPS server running atmyserver.com
port 636 as follows:openssl s_client -verify 10 -connect myserver.com:636 \ -CAfile <(keytool -list -rfc -keystore truststore.jks -storepass mypass)
- StartTLS
- To validate a truststore, run the following command:NOTEThe following example validates that a truststore named
truststore.jks
with passwordmypass
works for an LDAPS server running atmyserver.com
port 389 as follows:openssl s_client -verify 10 -connect myserver.com:389 -starttls ldap \ -CAfile <(keytool -list -rfc -keystore truststore.jks -storepass mypass)