Working with certificates in Java
This post contains a mix of java and certificate info. Note that you should definitely use the p12 format in Java. Using other types, like p8, usually end up causing issues in the end. One easy way is by creating a custom trust manager
The easiest way of doing this is: (See this link for a code example on stackoverflow
- Create a custom trust manager with your special certs
- Create a trust manager with the default certs
- Create a custom trust manager, which takes the custom and the default trust manager and try them both
Another way of doing it would be adding the certificate manually to the cacerts file.
Note that you will either need the full certificate chain for it to work, or just the root cert might also work.
Note that certs added to the java key store must be in DER-format. See below for converting between formats.
When adding with the keytool, you will either need to specify the path manually, or add it with the -cacerts
flag to add it to the main key store.
The keystore will ask you for password, but the password usually is changeit
Adding to keystore
# Replace FILEPATH with the cert-file and ALIAS with any given alias, which can be anything, but must be unique.
sudo keytool -keystore /etc/ssl/certs/java/cacerts -import -file FILEPATH -alias ALIAS
# Example of adding through a noninteractive script. Note that -cacerts is used instead of -keystore ...
keytool -noprompt -trustcacerts -storepass changeit -import -alias myserver -cacerts -file /tmp/server.der
Show contents of keystore
keytool -v -list -keystore path-to-keystore
OpenSSL generation commands
Generate self-signed root ca cert
openssl req -x509 -sha256 -days 1825 -newkey rsa:2048 -keyout rootca.key -out rootca.crt
OpenSSL conversion commands
Unpack whole p12 into pem file
openssl pkcs12 -in infile.p12 -out outfile.pem -nodes
Unpack key from p12
openssl pkcs12 -in infile.p12 -out outfile.key -nodes -nocerts
Pack a p12 from pem and key
openssl pkcs12 -export -inkey certfile.key -in certfile.pem -out certfile.p12
Convert PEM/CRT to or from DER
Change -inform
, -outform
, -in
and `-out- as appropriate
openssl x509 -outform der -in server.crt -out server.der
OpenSSL validation commands
Validate you have a key required by server
Validate that you can access an port protected by a key. You should get some verbose data but the connection should stay open.
openssl s_client -connect hostname:443 -cert outfile.pem -key outfile.key
Validate that you trust a server
This will verify your general settings. There will be a lot of text. Verify return code should be 0.
openssl s_client -connect ldaps-server:636 </dev/null
You can also add the –CAfile
or –CApath
flags for troubleshooting.
To use –CApath
you might need to run openssl rehash path/to/capath
after adding the certs if you have a chain.
Verify a certificate locally without connecting
openssl verify -show_chain server.crt
Check end date of pem file
openssl x509 -enddate -noout -in outfile.pem
Download a certificate from a server
Add –verify 5
to get intermediary certs
openssl s_client -connect the.ldap.server.net:636 -showcerts < /dev/null > server.crt
Java8 - Cannot use higher ciphers
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Ignore due to america. You need to manually enable good ciphers if you have a low version of Java8. Otherwise you can also upgrade to 8u161 and it will automatically work.