【问题标题】:SSL Socket connectionSSL 套接字连接
【发布时间】:2013-09-18 04:57:25
【问题描述】:

如何创建 SSL Socket 连接?

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

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

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

我已经使用以下代码在 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()));

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

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)

【问题讨论】:

    标签: java android sockets ssl client-server


    【解决方案1】:

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

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

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

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

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

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

    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();
    

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

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

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

    【讨论】:

    • 如果您要连接的服务器需要证书,您只需要证书即可建立 SSL 连接。同上一个密钥库。
    • 你是说证书是可选的吗?
    • 我说只有在服务器需要时才需要它。我不会将其描述为“可选”:更多依赖于配置。
    • 您在谈论用户证书,当然您是对的!另一方面,我不是,这是我的误解;)
    • 这里没有证据表明服务器没有证书。
    猜你喜欢
    • 2013-10-14
    • 2016-08-19
    • 2014-06-30
    • 1970-01-01
    • 2011-04-17
    • 2011-02-09
    • 1970-01-01
    • 2021-12-22
    • 2015-11-12
    相关资源
    最近更新 更多