Keytool creates a trusted self-signed certificate

I try to use (java) keytool to create a self-signed certificate, but when I try to use it, I get the following exception (see the bottom for the entire exception).

...<5 more exceptions above this> Caused by: sun.security.validator.ValidatorException: No trusted certificate found at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304) at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:107) at sun.security.validator.Validator.validate(Validator.java:203) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172) at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841) ... 22 more 

I know that I can get around this with this code:

 import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLSession; HostnameVerifier hv = new HostnameVerifier() { public boolean verify(String urlHostName, SSLSession session) { System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost()); return true; } }; HttpsURLConnection.setDefaultHostnameVerifier(hv); 

(a source)

But I am not interested in this, because I think that it creates a security hole. (please correct me if I am wrong).

Can someone point me in the right direction? Now I'm testing locally, so it's pretty easy to make a difference. I have access to server code, client code, and a .keystore file.

Update

I tried to use a single .keystore file for both the client and the server, but in the hope of simplifying my problems I created the .keystore server (see below) and client.truststore (see below). I am pretty sure that the certificates are correct, but if someone could verify, I would be grateful.

server.keystore

 hostname[username:/this/is/a/path][711]% keytool -list -keystore server.keystore -v Enter keystore password: Keystore type: JKS Keystore provider: SUN Your keystore contains 1 entry Alias name: hostname Creation date: Feb 4, 2010 Entry type: PrivateKeyEntry Certificate chain length: 1 Certificate[1]: Owner: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname Issuer: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname Serial number: 4b6b0ea7 Valid from: Thu Feb 04 13:15:03 EST 2010 until: Wed May 05 14:15:03 EDT 2010 Certificate fingerprints: MD5: 81:C0:3F:EC:AD:5B:7B:C4:DA:08:CC:D7:11:1F:1D:38 SHA1: F1:78:AD:C8:D0:3A:4C:0C:9A:4F:89:C0:2A:2F:E2:E6:D5:13:96:40 Signature algorithm name: SHA1withDSA Version: 3 ******************************************* ******************************************* 

client.truststore

 hostname[username:/this/is/a/path][713]% keytool -list -keystore client.truststore -v Enter keystore password: Keystore type: JKS Keystore provider: SUN Your keystore contains 1 entry Alias name: mykey Creation date: Feb 4, 2010 Entry type: trustedCertEntry Owner: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname Issuer: CN=hostname, OU=hostname, O=hostname, L=hostname, ST=hostname, C=hostname Serial number: 4b6b0ea7 Valid from: Thu Feb 04 13:15:03 EST 2010 until: Wed May 05 14:15:03 EDT 2010 Certificate fingerprints: MD5: 81:C0:3F:EC:AD:5B:7B:C4:DA:08:CC:D7:11:1F:1D:38 SHA1: F1:78:AD:C8:D0:3A:4C:0C:9A:4F:89:C0:2A:2F:E2:E6:D5:13:96:40 Signature algorithm name: SHA1withDSA Version: 3 ******************************************* ******************************************* 

Update

I thought it would be helpful to include all the exception:

 javax.xml.soap.SOAPException: java.io.IOException: Could not transmit message at org.jboss.ws.core.soap.SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:115) at org.jboss.ws.core.soap.SOAPConnectionImpl.call(SOAPConnectionImpl.java:66) at com.alcatel.tpapps.common.utils.SOAPClient.execute(SOAPClient.java:193) at com.alcatel.tpapps.common.utils.SOAPClient.main(SOAPClient.java:280) Caused by: java.io.IOException: Could not transmit message at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:192) at org.jboss.ws.core.client.SOAPRemotingConnection.invoke(SOAPRemotingConnection.java:77) at org.jboss.ws.core.soap.SOAPConnectionImpl.callInternal(SOAPConnectionImpl.java:106) ... 3 more Caused by: org.jboss.remoting.CannotConnectException: Can not connect http client invoker. sun.security.validator.ValidatorException: No trusted certificate found. at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:368) at org.jboss.remoting.transport.http.HTTPClientInvoker.transport(HTTPClientInvoker.java:148) at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:141) at org.jboss.remoting.Client.invoke(Client.java:1858) at org.jboss.remoting.Client.invoke(Client.java:718) at org.jboss.ws.core.client.RemotingConnectionImpl.invoke(RemotingConnectionImpl.java:171) ... 5 more Caused by: javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: No trusted certificate found at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:150) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1584) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:174) at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:168) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:848) at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:106) at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:495) at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:433) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:877) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1089) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1116) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1100) at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:402) at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:170) at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:857) at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230) at org.jboss.remoting.transport.http.HTTPClientInvoker.useHttpURLConnection(HTTPClientInvoker.java:288) ... 10 more Caused by: sun.security.validator.ValidatorException: No trusted certificate found at sun.security.validator.SimpleValidator.buildTrustedChain(SimpleValidator.java:304) at sun.security.validator.SimpleValidator.engineValidate(SimpleValidator.java:107) at sun.security.validator.Validator.validate(Validator.java:203) at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:172) at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(SSLContextImpl.java:320) at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:841) ... 22 more 
+6
java certificate web-services ssl-certificate keytool
source share
5 answers

You will need to “establish trust” between your server and client (I assume that you only need server-side authentication). This is because you are using self-signed certificates. This implies importing the server certificate into the client trust repository:

On the server side:

 keytool -keystore <keystore file> -alias <alias> -export -file <certfilename>.cert 

Copy the .cert file to the client side, and then:

 keytool -keystore <truststore file> -alias <alias> -import -file <certfilename>.cert 
+14
source share

You cannot split the keystore between the client and server because the keystore contains a private key. During authentication, the client skips certificates with private keys. As stated above, you need to deploy a trust server on the client side.

Certificates in the keystore do not behave the same, depending on how you generated or imported them.

The imported type of certificate entry (with a detailed listing of the entire keystore with -list -v ) is "trustedCertEntry". The generated certificate entry type is "PrivateKeyEntry". When you export a certificate, you only export its public key and an optional link to its issuer.

It looks like you need to export the self-signed certificate to the keystore as a trusted certificate in your trusted store (the names here make sense).

I would not do this because the SSL / TLS implementation probably does not support it. From a real-world point of view, this is like deploying a Verisign secret private key on some obscure web server for signing random pages, while the sole purpose of this private key is to remain secure and sign other certificates. SSL / TLS developers will probably not pollute their code with this use case, and in any case, the KeyUsage certificate extension may limit the use of the certificate for signing, preventing encryption.

This is why I suggest rebuilding the certificate chain for your test.

The keytool documentation contains an interesting part on chaining ( -gencert ), but this is a very skeletal example that does not cover key storage relationships. I improved it to mimic a third-party certificate authority.

The interim store of their-keystore.jks is a certificate issuing authority. I pass him the certificate chain ca2 -> ca1 -> ca with ca , which is considered as the root certificate. A chain is displayed with each certificate without a root (namely ca1 and ca2 ), referring to their issuer as Certificate[2] . Please note that each certificate is a "PrivateKeyEntry".

Then I pass my-keystore.jks these certificates in order: ca , ca1 , ca2 . I import ca using the -trustcacerts , which means that it becomes the root certificate. In my-keystore.jks each imported certificate is now "trustedCertEntry", which means that there is only a public key. Relations with the issuance are displayed only in the "Issuer" field, but this is normal, because trust relations are most important during import.

At this point, my-keystore.jks simulating an environment containing several trusted certificates, such as the new JRE. their-keystore.jks imitates the owners of these certificates, who have the right to sign certificate requests.

So I: I create a self-signed certificate e1 in my-keystore.jks , it is signed by ca2 (via their-keystore.jks ) and imports the result back into my-keystore.jks . e1 is still "PrivateKeyEntry" (since its private key remains in my-keystore.jks ), but now I have created the following chain: e1 -> ca2 -> ca1 . It seems that ca1 -> ca implicit if ca is a certification authority.

To create a trusted store, I simply import the certificates ca , ca1 and ca2 in the same way as for my-keystore.jks . Please note: I do not import e1 , since I expect the SSL / TLS client to check it on ca2 .

I think this is pretty close how everything works in the real world. It's nice that you have full control of the certificates and are not dependent on JRE cacerts.

Here is the code that I speak in practice. It seems to work with Jetty (client and server) until you turn off the certificate revocation list (topic left the next day).

 #!/bin/bash rm their-keystore.jks 2> /dev/null rm my-keystore.jks 2> /dev/null rm my-truststore.jks 2> /dev/null echo "====================================================" echo "Creating fake third-party chain ca2 -> ca1 -> ca ..." echo "====================================================" keytool -genkeypair -alias ca -dname cn=ca \ -validity 10000 -keyalg RSA -keysize 2048 \ -ext BasicConstraints:critical=ca:true,pathlen:10000 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass keytool -genkeypair -alias ca1 -dname cn=ca1 \ -validity 10000 -keyalg RSA -keysize 2048 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass keytool -genkeypair -alias ca2 -dname cn=ca2 \ -validity 10000 -keyalg RSA -keysize 2048 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass keytool -certreq -alias ca1 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -gencert -alias ca \ -ext KeyUsage:critical=keyCertSign \ -ext SubjectAlternativeName=dns:ca1 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -alias ca1 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass #echo "Debug exit" ; exit 0 keytool -certreq -alias ca2 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -gencert -alias ca1 \ -ext KeyUsage:critical=keyCertSign \ -ext SubjectAlternativeName=dns:ca2 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -alias ca2 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass keytool -list -v -storepass Storepass -keystore their-keystore.jks echo "====================================================================" echo "Fake third-party chain generated. Now generating my-keystore.jks ..." echo "====================================================================" read -p "Press a key to continue." # Import authority certificate chain keytool -exportcert -alias ca \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -trustcacerts -noprompt -alias ca \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass keytool -exportcert -alias ca1 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -noprompt -alias ca1 \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass keytool -exportcert -alias ca2 \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -noprompt -alias ca2 \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass # Create our own certificate, the authority signs it. keytool -genkeypair -alias e1 -dname cn=e1 \ -validity 10000 -keyalg RSA -keysize 2048 \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass keytool -certreq -alias e1 \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -gencert -alias ca2 \ -ext SubjectAlternativeName=dns:localhost \ -ext KeyUsage:critical=keyEncipherment,digitalSignature \ -ext ExtendedKeyUsage=serverAuth,clientAuth \ -keystore their-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -alias e1 \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass keytool -list -v -storepass Storepass -keystore my-keystore.jks echo "=================================================" echo "Keystore generated. Now generating truststore ..." echo "=================================================" read -p "Press a key to continue." keytool -exportcert -alias ca \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -trustcacerts -noprompt -alias ca \ -keystore my-truststore.jks -keypass Keypass -storepass Storepass keytool -exportcert -alias ca1 \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -noprompt -alias ca1 \ -keystore my-truststore.jks -keypass Keypass -storepass Storepass keytool -exportcert -alias ca2 \ -keystore my-keystore.jks -keypass Keypass -storepass Storepass \ | keytool -importcert -noprompt -alias ca2 \ -keystore my-truststore.jks -keypass Keypass -storepass Storepass keytool -list -v -storepass Storepass -keystore my-truststore.jks rm their-keystore.jks 2> /dev/null 
+9
source share

You must not do this. The keystore is strictly confidential. If you carry it to someone, you have deadly security. There is no point in doing this kind of thing, just to make it work, because it does not work - it's just a security breach. You must do it right :. Export from the server to the client's repository of trusted certificates, and from the client, if the repository of any server keystore

+3
source share

I do not understand. Do you use server key storage with the client? What is your use case? Are you trying to set up mutual authentication?

If so, you are mistaken. You will need a client key store (for a client self-signed certificate and private key) and a client trust store (for a "stand-alone" self-signed server certificate, that is, without its private key). Both of them differ from server key storage.

0
source share
 Springboot 2.1.5 , java 1.8, keytool(it is part of JDK 8) these are the steps to follow to generate the self signed ssl certifcate in spring boot 1. Generate self signed ssl certificate keytool -genkeypair -alias tomcat -keyalg RSA -keysize 2048 -storetype PKCS12 -keystore keystore.p12 -validity 3650 ex: D:\example> <here run the above command> if it is not working then make sure that your java bin path is set at environment variables to the PATH variable as C:\Program Files\Java\jdk1.8.0_191\bin 2. after key generation has done then copy that file in to the src/main/resources folder in your project 3. add key store properties in applicaiton.properties server.port: 8443 server.ssl.key-store:classpath:keystore.p12 server.ssl.key-store-password: test123 # change the pwd server.ssl.keyStoreType: PKCS12 server.ssl.keyAlias: tomcat 3. change your postman ssl verification settings to turn OFF go to settings and select the ssl verification to turn off now verify the url ( your applicaiton url) https://localhost:8443/test/hello 
-one
source share

All Articles