Phi*_*lip 5 ssl android self-signed httpurlconnection
我知道还有一些关于同一主题的其他问题,但是这些问题都不等于我的具体问题。
HttpURLConnection在我的 Android 应用程序中,我通过一些 RESTful 端点发出 Http 请求。其中一些端点使用自签名证书,其他端点则不使用。因此,我需要一种方法将自定义 KeyStore 添加到默认 HttpURLConnection 行为。
这是我现在的代码:
try {
KeyStore keyStore = getKeyStore(context);
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(keyStore);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "pasword".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
} catch (KeyStoreException | IOException | CertificateException | NoSuchAlgorithmException | UnrecoverableKeyException | KeyManagementException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
它可以工作,但仅适用于自签名证书,任何其他请求都会产生java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
因此,我正在寻找一种方法让 HttpURLConnection 识别自定义自签名证书而不破坏正常行为。
您基本上有两个选择:
我不推荐的选项 1 是创建一个不验证证书的自定义 TrustManager:
TrustManager[] trustAllCerts = new TrustManager[]{
new X509ExtendedTrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) {}
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) {}
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {}
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {}
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
KeyStore keyStore = getKeyStore(context);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, "pasword".toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
Run Code Online (Sandbox Code Playgroud)
如果服务器不需要客户端进行身份验证,您甚至可以删除 keymanagerfactory 并使用以下代码初始化 ssl 上下文:
TrustManager[] trustAllCerts = new TrustManager[]{
new X509ExtendedTrustManager() {
public void checkClientTrusted(X509Certificate[] chain, String authType, Socket socket) {}
public void checkServerTrusted(X509Certificate[] chain, String authType, Socket socket) {}
public void checkClientTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {}
public void checkServerTrusted(X509Certificate[] chain, String authType, SSLEngine engine) {}
public void checkClientTrusted(X509Certificate[] chain, String authType) {}
public void checkServerTrusted(X509Certificate[] chain, String authType) {}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4986 次 |
| 最近记录: |