[英]Add a self-signed SSL certificate to HttpURLConnection
我知道關於同一主題還有其他一些問題,但是這些問題都與我的具體問題不符。
在我的 Android 應用程序中,我通過HttpURLConnection
向某些 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();
}
它有效,但僅適用於自簽名證書,任何其他請求都會產生java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
所以,我正在尋找一種讓 HttpURLConnection 識別自定義自簽名證書而不破壞正常行為的方法。
您基本上有兩種選擇:
我不推薦的選項 1 是創建一個不驗證證書的自定義 TrustManager:
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
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());
如果服務器不需要客戶端進行身份驗證,您甚至可以刪除 keymanagerfactory 並使用以下代碼初始化 ssl 上下文:
TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.