最近,我已经实现了一项安全功能,以检查我的请求是否与有效主机连接。为此,我正在检查该主机的证书,并且在这种情况下使用了X509TrustManager。因此,如果X509TrustManager发现某个无效的证书,它将抛出异常,并根据该异常,向用户显示警报。但是问题是X509TrustManager仅在第一次时引发异常。但是,当我刷新相同的请求时,我没有收到无效的证书,也没有看到任何警报。下面我添加了我的实现。让我知道我的实施中的任何问题或X509TrustManager的任何已知问题。谢谢和问候。
final X509TrustManager finalTrustManager = x509TrustManager;
TrustManager[] trustAllCerts = new TrustManager[0];
if (finalTrustManager != null) {
trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
return finalTrustManager.getAcceptedIssuers();
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
try {
// If Application get any CertificateException in Splash screen we will show related alert in MainActivity
// We need to terminate app after showing alert but if we show alert in Splash screen it will get hide when Main Activity get visible.
// To avoid this scenario we added this implementation.
if (mIsSplashGetInvalidateCertificate && !(mLifecycleManager.getCurrentStackOfActivity().get(0) instanceof SplashActivity)) {
mAlertManager.showAlertMessageWithoutDuplicates(mLifecycleManager.getCurrentContext().getResources().getString(R.string.certificate_error_title), mLifecycleManager.getCurrentContext().getResources().getString(R.string.certificate_error_message), (FragmentActivity) mLifecycleManager.getCurrentStackOfActivity().get(0), true);
}
// Checking the certificate availability of host
if ((certs != null && certs.length != 0) && (authType != null && authType.length() != 0)) {
finalTrustManager.checkClientTrusted(certs, authType);
} else {
terminateApplicationWithAlert();
}
} catch (CertificateException e) {
terminateApplicationWithAlert();
}
}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
try {
if (mIsSplashGetInvalidateCertificate && !(mLifecycleManager.getCurrentStackOfActivity().get(0) instanceof SplashActivity)) {
mAlertManager.showAlertMessageWithoutDuplicates(mLifecycleManager.getCurrentContext().getResources().getString(R.string.certificate_error_title), mLifecycleManager.getCurrentContext().getResources().getString(R.string.certificate_error_message), (FragmentActivity) mLifecycleManager.getCurrentStackOfActivity().get(0), true);
}
if ((certs != null && certs.length != 0) && (authType != null && authType.length() != 0)) {
finalTrustManager.checkServerTrusted(certs, authType);
} else {
terminateApplicationWithAlert();
}
} catch (CertificateException e) {
terminateApplicationWithAlert();
}
}
}
};
}
您实际上并没有将证书标记为无效,因为您正在捕获CertificateException
并吞下它。通过不抛出CertificateException
,您是在告诉HTTP库无效证书有效,这大概是为了不使证书重新验证太多而进行的缓存。
您需要允许从CertificateException
方法中抛出X509TrustManager
,在HTTP调用站点中捕获错误,并从此处显示对话框。