带有netty服务器的Android客户端(SSLSocket)

时间:2015-01-12 16:47:03

标签: java android ssl netty

我已经创建了一个非常简单的Netty安全聊天服务器,如教程所描述的那样:

SelfSignedCertificate ssc = new SelfSignedCertificate();

SslContext sslCtx = SslContext.newServerContext(ssc.certificate(), ssc.privateKey());`

之后我创建了一个简单的SSLSocket来与Android手机进行通信。我通过另一个线程执行连接并将其配置如下:

protected SSLSocket getConnection(String ip, int port) throws IOException {
    try {
        KeyStore trustStore = KeyStore.getInstance("BKS");
        InputStream trustStoreStream = context.getResources().openRawResource(R.raw.server);
        trustStore.load(trustStoreStream, "myPassword".toCharArray());

        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
        trustManagerFactory.init(trustStore);

        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustManagerFactory.getTrustManagers(), null);

        SSLSocketFactory factory = sslContext.getSocketFactory();
        SSLSocket socket = (SSLSocket) factory.createSocket(ip, port);
        socket.setEnabledCipherSuites(SSLUtils.getCipherSuitesWhiteList(socket.getEnabledCipherSuites()));
        return socket;
    } catch (GeneralSecurityException e) {
        throw new IOException(e.getMessage());
    }
}

这样,我做了

sslsocket = getConnection(SERVERIP, SERVERPORT);

out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(sslsocket.getOutputStream())));

正是在这个" out = ..." line抛出以下异常:

  

01-12 14:43:16.002:W / System.err(9979):javax.net.ssl.SSLHandshakeException:?java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。   01-12 14:43:16:002:W / System.err(9979):at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:409)   01-12 14:43:16.012:W / System.err(9979):at com.android.org.conscrypt.OpenSSLSocketImpl $ SSLOutputStream。(OpenSSLSocketImpl.java:706)   01-12 14:43:16.012:W / System.err(9979):at com.android.org.conscrypt.OpenSSLSocketImpl.getOutputStream(OpenSSLSocketImpl.java:643)   01-12 14:43:16.012:W / System.err(9979):at com.mypath.connector.TCPClient.run(TCPClient.java:106)   01-12 14:43:16.012:W / System.err(9979):at com.mypath.SplashActivity $ connectTask.doInBackground(SplashActivity.java:48)   01-12 14:43:16.012:W / System.err(9979):at com.mypath.SplashActivity $ connectTask.doInBackground(SplashActivity.java:1)   01-12 14:43:16.012:W / System.err(9979):在android.os.AsyncTask $ 2.call(AsyncTask.java:288)   01-12 14:43:16.012:W / System.err(9979):at java.util.concurrent.FutureTask.run(FutureTask.java:237)   01-12 14:43:16.012:W / System.err(9979):在android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:231)   01-12 14:43:16.012:W / System.err(9979):at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)   01-12 14:43:16.012:W / System.err(9979):at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:587)   01-12 14:43:16.012:W / System.err(9979):at java.lang.Thread.run(Thread.java:841)   01-12 14:43:16.012:W / System.err(9979):引起:java.security.cert.CertificateException:java.security.cert.CertPathValidatorException:未找到证书路径的信任锚。   01-12 14:43:16.012:W / System.err(9979):at com.android.org.conscrypt.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:282)   01-12 14:43:16.012:W / System.err(9979):at com.android.org.conscrypt.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:202)   01-12 14:43:16.012:W / System.err(9979):at com.android.org.conscrypt.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:611)   01-12 14:43:16.012:W / System.err(9979):at com.android.org.conscrypt.NativeCrypto.SSL_do_handshake(Native Method)   01-12 14:43:16.012:W / System.err(9979):at com.android.org.conscrypt.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:405)   01-12 14:43:16.012:W / System.err(9979):......还有11个   01-12 14:43:16.012:W / System.err(9979):引起:java.security.cert.CertPathValidatorException:找不到证书路径的信任锚。   01-12 14:43:16.012:W / System.err(9979):... 16更多

有谁知道我做错了什么?

2 个答案:

答案 0 :(得分:0)

出于开发目的,您可以对所有TrustManager使用信任。这种“解决方案”根本不安全。

 TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

最佳解决方案是: Trusting all certificates using HttpClient over HTTPS

答案 1 :(得分:0)

您的客户端应该信任服务器证书,因此出于测试目的而不是使用JAVA的TrustManagerFactory并配置它有时单调乏味,您可以使用Netty的InsecureTrustManagerFactory。通过这种方式,您的客户端将信任服务器发送的任何证书。但是一定不要在生产中使用它,这是非常不安全的。

相关问题