I am working on a java App ( restEasy standalone app runs with java -jar so no container only jdk 8 ) it is a client for an external webservice, I made another app which is a sample web service on jetty for my client. both of them running locally or on my pc ( MYPC_NAME.mycomp.net)
( This is the solution to a problem and I need to understand why did i need to solve it like this; it will help any one who is having the same errors as well)
I generated keystores certs and truststores for both of them.
keytool -genkey -alias serverkey -storetype jks -keyalg RSA -keysize 2048 -keystore myapprestws.keystore -validity 730 -storepass "MYAPPS Private Keys" -dname "CN=mycomp.net, OU=BANK, O=clientws, L=City, ST=State, C=Country" -keypass "MYAPPS Keys"
keytool -genkey -alias clientkey -keystore myappwsclient.keystore -storepass "MYAPPS Private Keys" -dname "CN=mycomp.net, OU=SHARES, O=myapp, L=City, ST=State, C=Country" -keyalg RSA -keysize 2048 -storetype jks -validity 7 -keypass "MYAPPS Keys"
i tried to call the webservice from my standalone java app : https://localhost:8843/myapp/orders
at first i got an error on both sides On client side it said
Invalid certificate on target
on server end in debug mode it said the
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
to solve this I added the both the certs to JDK's cacerts ( as my certs were self signed) one by one first the client cert and then the server cert
i tried to call the webservice : https://localhost:8843/myapp/orders
it progressed to another error on client side it said :
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <localhost> doesn't match any of the subject alternative names: []
I regenerated the certs with SAN mycomp.net so any pc on my domain mycomp.net will be ok for this cert ( SAN did not take *.mycomp.net)
keytool -genkey -alias serverkey -storetype jks -keyalg RSA -keysize 2048 -keystore myapprestws.keystore -validity 730 -storepass "MYAPPS Private Keys" -dname "CN=myapp.net, OU=BANK, O=clientws, L=City, ST=State, C=Country" -keypass "MYAPPS Private Keys" -ext SAN=dns:mycomp.net
keytool -genkey -alias clientkey -keystore myappwsclient.keystore -storepass "MYAPPS Private Keys" -dname "CN=myapp.net, OU=SHARES, O=myapp, L=City, ST=State, C=Country" -keyalg RSA -keysize 2048 -storetype jks -validity 7 -keypass "MYAPPS Private Keys" -ext SAN=dns:mycomp.net
and added to JDK's cacert ( as they are self signed) after removing the previous ones
I thought it needed a host name so i changed my url to https://MYPC_NAME.mycomp.net:8843/myapp/orders
it progressed to another error :
javax.net.ssl.SSLPeerUnverifiedException: Certificate for <MYPC_NAME.mycomp.net> doesn't match any of the subject alternative names: [mycomp.net]
So i regenerated the certs
keytool -genkey -alias serverkey -storetype jks -keyalg RSA -keysize 2048 -keystore myapprestws.keystore -validity 730 -storepass "MYAPPS Private Keys" -dname "CN=myapp.net, OU=BANK, O=clientws, L=City, ST=State, C=Country" -keypass "MYAPPS Private Keys" -ext SAN=dns:MYPC_NAME.mycomp.net
keytool -genkey -alias clientkey -keystore myappwsclient.keystore -storepass "MYAPPS Private Keys" -dname "CN=myapp.net, OU=SHARES, O=myapp, L=City, ST=State, C=Country" -keyalg RSA -keysize 2048 -storetype jks -validity 7 -keypass "MYAPPS Private Keys" -ext SAN=dns:MYPC_NAME.mycomp.net
and added to JDK's cacert ( as they are self signed) after removing the previous ones
and I hit the url https://MYPC_NAME.comp.net:8843/myapp/orders and it worked
My question ( or beef ) with this solution.
Why did i need to add a SAN ?... I have worked with certs before and i didnt needed this SAN thing before, i have used the first keytool command i posted with -ext and that has worked. is this mandatory with keytool now with JDK 8?
What if i wanted to use OLD certs that were already generated and worked on other apps?
Also, the SAN is now very very specific. you can either define an ip in -ext SAN: ip:XXX.XXX.XXX.XXX or something. but then this cert with only work on machine that has the dns: MYPC_NAME.mycomp.net. this cert is not portable to other machine any more i can not ship it with build. previously, CN=localhost or CN=*.mycomp.net would be sufficient.
IS my solution correct ( just because it works doesn't mean it is the correct way right?)?
the Client that is the developer of the actual external Web service which my rest client would need to talk has not defined the SAN and their certs work.