单个证书添加
1.首先,需要将证书文件(.crt 格式)放置在 Android 项目的 asset 目录下。
image接下来,在 OkHttpClient.Builder() 中,使用setSslSocketFactory()方法来为 SSL 连接设置证书:
OkHttpClient client = new OkHttpClient.Builder()
.sslSocketFactory(getSslSocketFactory(context))
.build();
还需要实现 getSslSocketFactory:
private SSLSocketFactory getSslSocketFactory(Context context) {
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = context.getAssets().open("your_certificate_file.crt");
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
} finally {
caInput.close();
}
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
如果需要信任多个证书,可以使用 getTrustManagers() 方法添加多个证书。
private SSLSocketFactory getSSLSocketFactory(Context context) {
try {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
List<Certificate> certificates = new ArrayList<>();
certificates.add(cf.generateCertificate(context.getAssets().open("your_certificate_file_1.crt")));
certificates.add(cf.generateCertificate(context.getAssets().open("your_certificate_file_2.crt")));
// Create a KeyStore containing the trusted root certificates
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(null, null);
for (int i = 0; i < certificates.size(); i++) {
Certificate certificate = certificates.get(i);
String certificateAlias = Integer.toString(i);
keyStore.setCertificateEntry(certificateAlias, certificate);
}
// Create a TrustManager that trusts the CAs in our KeyStore
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
// Create an SSLContext that uses our TrustManager
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, tmf.getTrustManagers(), null);
return sslContext.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
还可以使用信任所有证书的模式(忽略SSL证书模式)
private static OkHttpClient getUnsafeOkHttpClient() {
try {
// 创建不验证证书链的TrustManager
final TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) throws CertificateException {}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
}
};
// 使用不验证证书链的TrustManager初始化SSLContext
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// 创建只使用通过SSLContext初始化的TrustManager的SSL套接字工厂
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
// 创建可以忽略证书链的OkHttpClient
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
.hostnameVerifier((hostname, session) -> true);
return builder.build();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
网友评论