现在 SSLSocketFactory 已在 Android 上弃用,处理客户端证书身份验证的最佳方法是什么?
Now that SSLSocketFactory is deprecated on Android, what would be the best way to handle Client Certificate Authentication?
我正在开发一个需要客户端证书身份验证(使用 PKCS 12 文件)的 Android 应用程序。
在弃用所有 apache.http.*
之后,我们开始了一项相当大的网络层重构工作,我们决定使用 OkHttp 作为替代品,到目前为止我非常喜欢它。
但是,我还没有找到任何其他方法来处理客户端证书身份验证而不使用 SSLSocketFactory
、OkHttp 或其他任何与此相关的方法。那么在这种特殊情况下最好的行动方案是什么?
OkHttp 是否有另一种方法来处理这种身份验证?
显然,有两个 SSLSocketFactory
类。 HttpClient 有自己的一个,它与 HttpClient 的其余部分一起被弃用。但是,其他人都将使用 the more conventional javax.net.ssl
edition of SSLSocketFactory
,它并未被弃用(感谢 $DEITY
)。
如果您使用 https,则必须使用有效的证书。在您的开发阶段,您必须信任证书,如何?
sslSocketFactory(SSLSocketFactory sslSocketFactory)
已弃用并被 sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager)
取代,您必须更新 gradle 文件
下面的代码片段将帮助您获得一个信任任何 ssl 证书的可信 OkHttpClient。
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { trustManager }, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, trustManager);
看,我找到了一些解决方案,并且在我这边运行良好。检查我是如何集成的..
OkHttpClient.Builder client = new OkHttpClient.Builder();
在此处添加客户端实例的所有属性
。
.
.
并为 sslSocketFactory 添加这些代码行:
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
client.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
client.hostnameVerifier((hostname, session) -> true);
} catch (Exception e) {
throw new RuntimeException(e);
}
我正在开发一个需要客户端证书身份验证(使用 PKCS 12 文件)的 Android 应用程序。
在弃用所有 apache.http.*
之后,我们开始了一项相当大的网络层重构工作,我们决定使用 OkHttp 作为替代品,到目前为止我非常喜欢它。
但是,我还没有找到任何其他方法来处理客户端证书身份验证而不使用 SSLSocketFactory
、OkHttp 或其他任何与此相关的方法。那么在这种特殊情况下最好的行动方案是什么?
OkHttp 是否有另一种方法来处理这种身份验证?
显然,有两个 SSLSocketFactory
类。 HttpClient 有自己的一个,它与 HttpClient 的其余部分一起被弃用。但是,其他人都将使用 the more conventional javax.net.ssl
edition of SSLSocketFactory
,它并未被弃用(感谢 $DEITY
)。
如果您使用 https,则必须使用有效的证书。在您的开发阶段,您必须信任证书,如何?
sslSocketFactory(SSLSocketFactory sslSocketFactory)
已弃用并被 sslSocketFactory(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager)
取代,您必须更新 gradle 文件
下面的代码片段将帮助您获得一个信任任何 ssl 证书的可信 OkHttpClient。
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new TrustManager[] { trustManager }, null);
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(sslSocketFactory, trustManager);
看,我找到了一些解决方案,并且在我这边运行良好。检查我是如何集成的..
OkHttpClient.Builder client = new OkHttpClient.Builder();
在此处添加客户端实例的所有属性
。 . .
并为 sslSocketFactory 添加这些代码行:
try {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[]{};
}
}
};
// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
client.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]);
client.hostnameVerifier((hostname, session) -> true);
} catch (Exception e) {
throw new RuntimeException(e);
}