"未找到证书路径的信任锚"在Android SSL Socket客户端

时间:2014-10-30 23:17:04

标签: java android ssl

我正在尝试使用Android客户端应用连接到SSL服务器。 服务器有JKS证书,使用Portecle转换为BKS。 服务器代码非常简单:

public class EchoServer {
public static void main(String[] arstring) {
    try {
        SSLServerSocketFactory sslserversocketfactory =
                (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
        SSLServerSocket sslserversocket =
                (SSLServerSocket) sslserversocketfactory.createServerSocket(25000);
        SSLSocket sslsocket = (SSLSocket) sslserversocket.accept();

        InputStream inputstream = sslsocket.getInputStream();
        InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
        BufferedReader bufferedreader = new BufferedReader(inputstreamreader);

        String string = null;
        while ((string = bufferedreader.readLine()) != null) {
            System.out.println(string);
            System.out.flush();
        }
    } catch (Exception exception) {
        exception.printStackTrace();
    }
}

}

服务器正常工作(我使用相同的证书用java客户端应用程序测试它,它没有显示任何问题)。 现在,我使用Portecle在BKS证书中转换了JKS服务器证书,但Android无法连接到服务器。 Android代码看起来像

            InputStream certificato = getResources().openRawResource(R.raw.keystore);
            KeyStore trustStore = null;
            try {
                String tfmAlgorithm=TrustManagerFactory.getDefaultAlgorithm();
                trustStore = KeyStore.getInstance("BKS");
                trustStore.load(certificato, "123456".toCharArray());
                TrustManagerFactory tmf=TrustManagerFactory.getInstance(tfmAlgorithm);
                tmf.init(trustStore);
                SSLContext slc=SSLContext.getInstance("SSL");
                slc.init(null,tmf.getTrustManagers(),new SecureRandom());
                SSLSocketFactory fs=slc.getSocketFactory();
                Socket socket = fs.createSocket("10.0.0.2", 25000);

                /*InputStream inputstream = socket.getInputStream();
                InputStreamReader inputstreamreader = new InputStreamReader(inputstream);
                BufferedReader bufferedreader = new BufferedReader(inputstreamreader);*/

                OutputStream os = socket.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(os);
                BufferedWriter bw = new BufferedWriter(osw);

                String sendMessage = "brova";
                bw.write(sendMessage + "\n");
                bw.flush();

                System.out.println("Message sent to the server : " + sendMessage);
            } catch (KeyStoreException e) {
                e.printStackTrace();
            } catch (CertificateException e) {
                e.printStackTrace();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
            return "OK";
        }

它应该可以工作,因为它与我在Java PC客户端上使用的代码相同,但它引发了这个异常堆栈:

10-31 00:05:09.068   9921-10142/com.example.furt.myapplication W/System.err﹕ javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
10-31 00:05:09.068   9921-10142/com.example.furt.myapplication W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:375)
10-31 00:05:09.068   9921-10142/com.example.furt.myapplication W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl$SSLOutputStream.<init>(OpenSSLSocketImpl.java:669)
10-31 00:05:09.068   9921-10142/com.example.furt.myapplication W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.getOutputStream(OpenSSLSocketImpl.java:606)
10-31 00:05:09.068   9921-10142/com.example.furt.myapplication W/System.err﹕ at com.example.furt.myapplication.MyActivity$richiestaServer.doInBackground(MyActivity.java:235)
10-31 00:05:09.068   9921-10142/com.example.furt.myapplication W/System.err﹕ at com.example.furt.myapplication.MyActivity$richiestaServer.doInBackground(MyActivity.java:166)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:137)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at java.lang.Thread.run(Thread.java:864)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:192)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:163)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:574)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:372)
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ ... 11 more
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ Caused by: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
10-31 00:05:09.078   9921-10142/com.example.furt.myapplication W/System.err﹕ ... 16 more
10-31 00:05:09.128    9921-9921/com.example.furt.myapplication D/memalloc﹕ ion: Mapped buffer base:0x50f8b000 size:61440 offset:0 fd:80
10-31 00:05:09.128    9921-9921/com.example.furt.myapplication D/memalloc﹕ ion: Mapped buffer base:0x4f274000 size:4096 offset:0 fd:82
10-31 00:05:11.088    9921-9921/com.example.furt.myapplication D/memalloc﹕ ion: Unmapping buffer  base:0x50f8b000 size:61440
10-31 00:05:11.088    9921-9921/com.example.furt.myapplication D/memalloc﹕ ion: Unmapping buffer  base:0x4f274000 size:4096
10-31 00:06:11.878    9921-9921/com.example.furt.myapplication I/InputMethodManager﹕ startInput, mServedView=android.widget.EditText@417e4420, inputType=0x81, pid=9921

任何人都可以解释原因吗?我经常读到,“找不到证书路径的信任锚”是由于缺少TrustManager,但我的代码应该引用使用我的证书的TrustManagerFactory。 难道我做错了什么? 非常感谢你提前!

0 个答案:

没有答案