Java Exception on SSLSocket creation

被刻印的时光 ゝ 提交于 2019-12-01 13:12:13

问题


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.


回答1:


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!




回答2:


I got the solution from another way, I share it for someone who comes here with the same problem:

I need add this code

System.setProperty("javax.net.ssl.trustStoreType","JCEKS");

because by default it expects a JKS type.




回答3:


The file you imported (Server.cer) is not in the format java is expecting. You told keytool the format was JCEKS. I believe that means it's a full keystore, which is not likely for a file named Server.cer.

You may have wanted to use -type PKCS12 instead.




回答4:


Thanks for your Answer... Solved my problem by putting this code :

System.setProperty("javax.net.ssl.trustStoreType","JCEKS");

Code as follows :

System.setProperty("javax.net.ssl.keyStore", CommonUtils.getKeystorePath());
System.setProperty("javax.net.ssl.keyStorePassword", 
                   CommonUtils.getKeystorePassword());
System.setProperty("javax.net.ssl.trustStore", 
                   CommonUtils.getTruststorePath());
System.setProperty("javax.net.ssl.trustStorePassword", 
                   CommonUtils.getTruststorePassword());
System.setProperty("javax.net.ssl.trustStoreType","JCEKS");


来源:https://stackoverflow.com/questions/22423063/java-exception-on-sslsocket-creation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!