title: SSL certificate needs SAN
body: <p>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)</p>
  
  <p>( 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)</p>
  
  <p>I generated keystores certs and truststores for both of them. </p>
  
  <pre><code>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"
  </code></pre>
  
  <p>i tried to call the webservice from my standalone java app : <code>https://localhost:8843/myapp/orders</code></p>
  
  <p>at first i got an error on both sides
  On client side it said </p>
  
  <pre><code>Invalid certificate on target
  </code></pre>
  
  <p>on server end in debug mode it said the </p>
  
  <pre><code>Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
  </code></pre>
  
  <p><strong>to solve</strong> 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 </p>
  
  <p>i tried to call the webservice : <a href="https://localhost:8843/myapp/orders" rel="nofollow noreferrer">https://localhost:8843/myapp/orders</a></p>
  
  <p>it progressed to another error on client side it said  :</p>
  
  <pre><code>javax.net.ssl.SSLPeerUnverifiedException: Certificate for &lt;localhost&gt; doesn't match any of the subject alternative names: []
  </code></pre>
  
  <p>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)</p>
  
  <pre><code>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
  </code></pre>
  
  <p>and added to JDK's cacert ( as they are self signed) after removing the previous ones</p>
  
  <p>I thought it needed  a host name so i changed my url to 
  <a href="https://MYPC_NAME.mycomp.net:8843/myapp/orders" rel="nofollow noreferrer">https://MYPC_NAME.mycomp.net:8843/myapp/orders</a></p>
  
  <p>it progressed to another error :</p>
  
  <pre><code>javax.net.ssl.SSLPeerUnverifiedException: Certificate for &lt;MYPC_NAME.mycomp.net&gt; doesn't match any of the subject alternative names: [mycomp.net]
  </code></pre>
  
  <p>So i regenerated the certs </p>
  
  <pre><code>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
  </code></pre>
  
  <p>and added to JDK's cacert ( as they are self signed) after removing the previous ones</p>
  
  <p>and I hit the url <a href="https://MYPC_NAME.comp.net:8843/myapp/orders" rel="nofollow noreferrer">https://MYPC_NAME.comp.net:8843/myapp/orders</a> and it worked </p>
  
  <p>My question ( or beef ) with this solution. </p>
  
  <p>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?</p>
  
  <p>What if i wanted to use OLD certs that were already generated and worked on other apps?</p>
  
  <p>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.</p>
  
  <p>IS my solution correct ( just because it works doesn't mean it is the correct way right?)?</p>
  
  <p>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. </p>