gpt4 book ai didi

android - 在 WebView loadUrl() 中信任证书颁发机构

转载 作者:太空宇宙 更新时间:2023-11-03 13:13:35 43 4
gpt4 key购买 nike

根据安全扫描程序的结果,我需要限制应用信任的证书颁发机构。

扫描结果指向webView.loadUrl("https://example.com/page");这一行。我看到了如何创建一个使用我的 TrustManager 的 SslSocketFactory,但我在 WebView 中没有看到允许我设置它的 API。

https://developer.android.com/training/articles/security-ssl.html#UnknownCa

有哪些可能的方法可以实现这一点?

最佳答案

我认为 WebViewClientonReceivedSslError 方法将是一个很好的切入点。

首先,遵循来自 https://developer.android.com/training/articles/security-ssl.html#UnknownCa 的完全相同的 fragment 准备 TrustManager。

    TrustManagerFactory tmf = null;

private void initTrustStore() throws
java.security.cert.CertificateException, FileNotFoundException,
IOException, KeyStoreException, NoSuchAlgorithmException {

// Create a KeyStore containing our trusted CAs
String keyStoreType = KeyStore.getDefaultType();
KeyStore trustedKeyStore = KeyStore.getInstance(keyStoreType);
trustedKeyStore.load(null, null);

CertificateFactory cf = CertificateFactory.getInstance("X.509");

InputStream caInput = new BufferedInputStream(
getResources().getAssets().open("ca.crt"));
Certificate ca;
try {
ca = cf.generateCertificate(caInput);
Log.d(TAG, "ca-root DN=" + ((X509Certificate) ca).getSubjectDN());
}
finally {
caInput.close();
}
trustedKeyStore.setCertificateEntry("ca", ca);

// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(trustedKeyStore);

}

然后,扩展自定义 WebViewClient 类,检查来自 https://stackoverflow.com/a/6379434/1099884 的 fragment

private class CheckServerTrustedWebViewClient extends WebViewClient{
public void onReceivedSslError(WebView view, final SslErrorHandler handler, SslError error) {
Log.d(TAG, "onReceivedSslError");
boolean passVerify = false;

if(error.getPrimaryError() == SslError.SSL_UNTRUSTED){
SslCertificate cert = error.getCertificate();
String subjectDN = cert.getIssuedTo().getDName();
Log.d(TAG, "subjectDN: "+subjectDN);
try{
Field f = cert.getClass().getDeclaredField("mX509Certificate");
f.setAccessible(true);
X509Certificate x509 = (X509Certificate)f.get(cert);

X509Certificate[] chain = {x509};
for (TrustManager trustManager: tmf.getTrustManagers()) {
if (trustManager instanceof X509TrustManager) {
X509TrustManager x509TrustManager = (X509TrustManager)trustManager;
try{
x509TrustManager.checkServerTrusted(chain, "generic");
passVerify = true;break;
}catch(Exception e){
Log.e(TAG, "verify trustManager failed", e);
passVerify = false;
}
}
}
Log.d(TAG, "passVerify: "+passVerify);
}catch(Exception e){
Log.e(TAG, "verify cert fail", e);
}
}
if(passVerify == true)handler.proceed();
else handler.cancel();

}

}

最后,将CheckServerTrustedWebViewClient设置为WebView

webView.setWebViewClient(new CheckServerTrustedWebViewClient());

但是,有一个问题。准备好的 CA 证书与服务器的签名完全相同(中间 CA 不是根 CA)。只提供根 CA 证书是行不通的。 TrustManager 不能在运行时下载服务器证书链吗?有什么建议吗?

关于android - 在 WebView loadUrl() 中信任证书颁发机构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40349141/

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com