我正在尝试与远程服务器建立安全通信,但遗憾的是,它已由自己的证书颁发机构签名。我在这里阅读官方的android文档:https://developer.android.com/training/articles/security-ssl.html,这里写的是,当证书颁发机构不在android列表中时,你需要自己接受服务器证书。所以我这样做了(再次来自文档):
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.certificate);
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
KeyStore keyStore = KeyStore.getInstance(keyStoreType);
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
context.init(null, tmf.getTrustManagers(), null);
HttpsURLConnection urlConnection = (HttpsURLConnection)url.openConnection();
urlConnection.setSSLSocketFactory(context.getSocketFactory());
InputStream in = urlConnection.getInputStream();
copyInputStreamToOutputStream(in, System.out);
但它不起作用,我收到错误:
10-10 09:48:17.320: W/System.err(27787): javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: TrustAnchor found but certificate validation failed.
10-10 09:48:17.350: W/System.err(27787): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:401)
10-10 09:48:17.350: W/System.err(27787): at libcore.net.http.HttpConnection.setupSecureSocket(HttpConnection.java:209)
10-10 09:48:17.350: W/System.err(27787): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.makeSslConnection(HttpsURLConnectionImpl.java:478)
10-10 09:48:17.350: W/System.err(27787): at libcore.net.http.HttpsURLConnectionImpl$HttpsEngine.connect(HttpsURLConnectionImpl.java:433)
10-10 09:48:17.350: W/System.err(27787): at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
10-10 09:48:17.370: W/System.err(27787): at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
10-10 09:48:17.400: W/System.err(27787): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:282)
10-10 09:48:17.400: W/System.err(27787): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
10-10 09:48:17.400: W/System.err(27787): at libcore.net.http.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:271)
10-10 09:48:17.400: W/System.err(27787): at com.myapp..webservice.RequestConfigurationAsyncTask.doInBackground(RequestConfigurationAsyncTask.java:36)
10-10 09:48:17.411: W/System.err(27787): at com.myapp..webservice.RequestConfigurationAsyncTask.doInBackground(RequestConfigurationAsyncTask.java:1)
10-10 09:48:17.411: W/System.err(27787): at android.os.AsyncTask$2.call(AsyncTask.java:287)
10-10 09:48:17.441: W/System.err(27787): at java.util.concurrent.FutureTask.run(FutureTask.java:234)
10-10 09:48:17.441: W/System.err(27787): at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
10-10 09:48:17.441: W/System.err(27787): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
10-10 09:48:17.441: W/System.err(27787): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
10-10 09:48:17.441: W/System.err(27787): at java.lang.Thread.run(Thread.java:841)
10-10 09:48:17.461: W/System.err(27787): Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: TrustAnchor found but certificate validation failed.
10-10 09:48:17.461: W/System.err(27787): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:308)
10-10 09:48:17.461: W/System.err(27787): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkServerTrusted(TrustManagerImpl.java:202)
10-10 09:48:17.471: W/System.err(27787): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.verifyCertificateChain(OpenSSLSocketImpl.java:595)
10-10 09:48:17.471: W/System.err(27787): at org.apache.harmony.xnet.provider.jsse.NativeCrypto.SSL_do_handshake(Native Method)
10-10 09:48:17.471: W/System.err(27787): at org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl.startHandshake(OpenSSLSocketImpl.java:398)
10-10 09:48:17.471: W/System.err(27787): ... 16 more
10-10 09:48:17.471: W/System.err(27787): Caused by: java.security.cert.CertPathValidatorException: TrustAnchor found but certificate validation failed.
10-10 09:48:17.511: W/System.err(27787): at com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:122)
10-10 09:48:17.511: W/System.err(27787): at java.security.cert.CertPathValidator.validate(CertPathValidator.java:190)
10-10 09:48:17.571: W/System.err(27787): at org.apache.harmony.xnet.provider.jsse.TrustManagerImpl.checkTrusted(TrustManagerImpl.java:295)
10-10 09:48:17.591: W/System.err(27787): ... 20 more
10-10 09:48:17.591: W/System.err(27787): Caused by: com.android.org.bouncycastle.jce.provider.AnnotatedException: TrustAnchor found but certificate validation failed.
10-10 09:48:17.591: W/System.err(27787): at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.findTrustAnchor(CertPathValidatorUtilities.java:235)
10-10 09:48:17.591: W/System.err(27787): at com.android.org.bouncycastle.jce.provider.PKIXCertPathValidatorSpi.engineValidate(PKIXCertPathValidatorSpi.java:117)
10-10 09:48:17.591: W/System.err(27787): ... 22 more
10-10 09:48:17.591: W/System.err(27787): Caused by: java.security.SignatureException: Signature was not verified
10-10 09:48:17.591: W/System.err(27787): at org.apache.harmony.security.provider.cert.X509CertImpl.verify(X509CertImpl.java:384)
10-10 09:48:17.601: W/System.err(27787): at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.verifyX509Certificate(CertPathValidatorUtilities.java:1427)
10-10 09:48:17.621: W/System.err(27787): at com.android.org.bouncycastle.jce.provider.CertPathValidatorUtilities.findTrustAnchor(CertPathValidatorUtilities.java:222)
10-10 09:48:17.621: W/System.err(27787): ... 23 more
为什么我找到 TrustAnchor但证书验证失败?看起来像证书已加载,但它不正确或有效 - 但我通过网络浏览器下载了页面证书(以crt,pem格式,但没有任何效果)所以它应该工作。怎么了?
答案 0 :(得分:1)
有三个原因,请查看以下链接
颁发服务器证书的CA未知 服务器证书未经CA签名,但已自签名 服务器配置缺少中间CA
<强> https://developer.android.com/training/articles/security-ssl.html 强>
答案 1 :(得分:0)
这在普通的java应用程序中对我有用,而不是在android中。
Security.insertProviderAt(new org.bouncycastle.jce.provider.BouncyCastleProvider(),1);