«Не найдена доверенная привязка для пути сертификации» в клиенте Android SSL Socket
Я пытаюсь подключиться к серверу SSL с помощью клиентского приложения Android. Сервер имеет свой JKS-сертификат, который был преобразован в BKS с помощью Portecle. Код сервера очень прост:
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, используя тот же сертификат, и он не показал проблем). Теперь я преобразовал сертификат сервера JKS в сертификат BKS с помощью Portecle, но 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, который использует мой сертификат. Я делаю что-то неправильно? Заранее большое спасибо!