In the code:
System.setProperty("javax.net.ssl.trustStore", cacerts);
System.setProperty("javax.net.ssl.trustStorePassword", pwdCacerts);
SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket("localhost", port);
I obtain a Java Exception:
java.net.SocketException: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
at javax.net.ssl.DefaultSSLSocketFactory.throwException(Unknown Source)
at javax.net.ssl.DefaultSSLSocketFactory.createSocket(Unknown Source)
at PracticaRO.Cliente.main(Cliente.java:24)
Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
at java.security.Provider$Service.newInstance(Unknown Source)
at sun.security.jca.GetInstance.getInstance(Unknown Source)
at sun.security.jca.GetInstance.getInstance(Unknown Source)
at javax.net.ssl.SSLContext.getInstance(Unknown Source)
at javax.net.ssl.SSLContext.getDefault(Unknown Source)
at javax.net.ssl.SSLSocketFactory.getDefault(Unknown Source)
at PracticaRO.Cliente.main(Cliente.java:23)
Caused by: java.io.IOException: Invalid keystore format
at sun.security.provider.JavaKeyStore.engineLoad(Unknown Source)
at sun.security.provider.JavaKeyStore$JKS.engineLoad(Unknown Source)
at java.security.KeyStore.load(Unknown Source)
at sun.security.ssl.TrustManagerFactoryImpl.getCacertsKeyStore(Unknown Source)
at sun.security.ssl.SSLContextImpl$DefaultSSLContext.getDefaultTrustManager(Unknown Source)
at sun.security.ssl.SSLContextImpl$DefaultSSLContext.<init>(Unknown Source)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
... 7 more
It worked fine until I imported a new public key into cacerts with -keytool -import -keystore cacerts -alias kpServer type JCEKS -file Server.cer
what caused the exception above.
Thanks in advance for any help.
I'm going to walk you through setup process. I suggest you use one password for everything just for you not to get confuse with it at first.
Follow this steps:
1. On Command Line:
To create a Public/Private Key Pair using RSA, 2048 bits, entity name is "secureEntity", stored in file "server.keyStore".
1.1 keytool -genkeypair -alias secureEntity -keyalg RSA -keysize 2048 - keystone server.keyStore
That command stored a Private Key and a Public Key for "secureEntity".
The Private Key, only you should have access to it (by knowing file password).
The Public Key is stored as a Certificate, so it follows X509 Certificate protocol fields. That way we can assume it contains a public key, and this public key is associated to "secureEntity".
And this is what we need to know for us to validate the certificate sent by server to client.
SSL first step validation is made by client, so the client validates the server in first place.
So now that we have generated a certificate and it is stored in server.keyStore we can export it in order to be able to import it into one or more trustStore.
The way we do it:
1.2 keytool -exportcert -alias secureEntity -file exported.cer -keystore server.keystore
So now we can add to our really trustStore file, and it will ask us to confirm that we really trust that entity right after the import. If the file doesn't exists it well be automatically created.
1.3 keytool -importcert -alias secureEntity -keystore trustedEntities.trustStore -file exported.cer
Now for convenience lets import it to a file that only contains server certificate:
1.4 keytool -importcert -alias secureEntity -keystore serverKeys.keyStore -file exported.cer
So now your server should have a private and public key (certificate).
In JAVA:
Client Side:
System.setProperty("javax.net.ssl.trustStore","trustedEntities.trustStore")
and Create sslsocket here
Server Side:
System.setProperty("javax.net.ssl.keyStore", "serverKeys.keyStore")
System.setProperty("javax.net.ssl.keyStorePassword", "serverKeys.keyStore FILE PASSWORD THAT YOU DEFINED BEFORE")
Create a server ssl and thats it. Hope this helps. Cheers!