Java SSL 套接字连接

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18787419/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:03:13  来源:igfitidea点击:

SSL Socket connection

javaandroidsocketssslclient-server

提问by Victor

How can I create a SSL Socket connection?

如何创建 SSL 套接字连接?

I realy need to create a keystore? This keystore should be shared with all my client applications?

我真的需要创建一个密钥库吗?这个密钥库应该与我所有的客户端应用程序共享吗?

I have create a server with the following code:

我使用以下代码创建了一个服务器:

SSLServerSocketFactory sslserversocketfactory = (SSLServerSocketFactory) SSLServerSocketFactory
                    .getDefault();
SSLServerSocket sslserversocket = (SSLServerSocket) sslserversocketfactory
                    .createServerSocket(ServerProperties.getInstance()
                            .getVSSPAuthenticationPort());

I have create a client on android with the following code:

我使用以下代码在 android 上创建了一个客户端:

SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory
                .getDefault();
SSLSocket sslsocket = (SSLSocket) sslsocketfactory.createSocket(
                host, authPort);

sslsocket.startHandshake();

BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(
                sslsocket.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(
                sslsocket.getInputStream()));

But when I try to connect, the following error is throwed:

但是当我尝试连接时,抛出以下错误:

javax.net.ssl.SSLHandshakeException: no cipher suites in common
    at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
    at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1886)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:276)
    at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:266)
    at sun.security.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:894)
    at sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:622)
    at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:167)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339)
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323)

采纳答案by VGe0rge

You need a certificate to establish an ssl connection, you can load the certificate inside a keystore or you can load the certificate itself. I will show some examples for the keystore option.

您需要一个证书来建立 ssl 连接,您可以在密钥库中加载证书,也可以加载证书本身。我将展示一些关于 keystore 选项的例子。

Your code needs some parameters to run :

您的代码需要一些参数才能运行:

java -Djavax.net.ssl.keyStore=keyStoreFile -Djavax.net.ssl.keyStorePassword=keystorePassword Server

You can also load the keystore with java code , the simplest solution for this is to set the system properties:

您还可以使用 java 代码加载密钥库,最简单的解决方案是设置系统属性:

System.setProperty("javax.net.ssl.keyStore", 'keystoreFile');
System.setProperty("javax.net.ssl.keyStorePassword", 'keystorePassword ');

Also you can load the keystore with a different way, its more complicated but you have the ability to do more complex things :

你也可以用不同的方式加载密钥库,它更复杂,但你有能力做更复杂的事情:

KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("keystoreFile"), "keystorePassword".toCharArray());

KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(ks, "keystorePassword".toCharArray());

TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509"); 
tmf.init(ks);

SSLContext sc = SSLContext.getInstance("TLS"); 
TrustManager[] trustManagers = tmf.getTrustManagers(); 
sc.init(kmf.getKeyManagers(), trustManagers, null); 

SSLServerSocketFactory ssf = sc.getServerSocketFactory(); 
SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(serverport);
SSLSocket c = (SSLSocket) s.accept();

For the clients there are a few changes in the code last lines, the 3 last lines will be replaced with these :

对于客户端,代码的最后几行有一些更改,最后 3 行将替换为:

SSLSocketFactory ssf = sc.getSocketFactory(); 
SSLSocket s = (SSLSocket) ssf.createSocket(serverip, serverport);
s.startHandshake();

If you want to load a keystore for android the type will have to be "BKS" and not "JKS". You can find easily resources for creating a keystore.

如果您想为 android 加载密钥库,则类型必须是“BKS”而不是“JKS”。您可以轻松找到用于创建密钥库的资源。