0

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.

sarmahdi
  • 1,098
  • 4
  • 21
  • 61
  • 1
    *Why did i need to add a SAN ?* Because using the CN is now deprecated, see https://stackoverflow.com/questions/5935369/ssl-how-do-common-names-cn-and-subject-alternative-names-san-work-together for details. You can put SANs as wildcards this does not change anything in that regard. The certificate is portable, you just need to use the proper name. As for localhost, have a look at https://letsencrypt.org/docs/certificates-for-localhost/ – Patrick Mevzek Aug 06 '18 at 23:48
  • Also please do not use any name and IP (and specifically **NOT** 1.1.1.1 that is a true IP with a live service on it, and certainly not yours) you imagine to obfuscate things. If you really need to obfuscate please use guidance from RFC2606 and RFC5737. – Patrick Mevzek Aug 06 '18 at 23:50
  • @PatrickMevzek Thanks for the answer Do you mean "do not use any name and IP " regarding the post or the cert. I think you meant in the post so i have changed the IP to XXX format. does the name mycomp has any issue? – sarmahdi Aug 07 '18 at 00:29
  • @PatrickMevzek "You can put SANs as wildcards " In keytool i did but it didnt let me, said i need a letter in the beginning. " you just need to use the proper name" I am not sure what do you mean by proper name. – sarmahdi Aug 07 '18 at 00:33

0 Answers0