Check in the onReceivedSslError() method of a WebViewClient if a certificate is signed from a specific self-signed CA(如果证书是从特定的自签名 CA 签名的,请检查 WebViewClient 的 onReceivedSslError() 方法)
问题描述
我想覆盖 WebViewClient
的 onReceivedSslError()
.在这里,我想检查 error.getCertificate()
证书是否由自签名 CA 签名,仅在这种情况下,调用 handler.proceed()代码>.在伪代码中:
I would like to override the onReceivedSslError()
of a WebViewClient
. Here I want to check if the error.getCertificate()
certificate is signed from a self-signed CA and, only in this case, call the handler.proceed()
. In pseudo-code:
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
SslCertificate serverCertificate = error.getCertificate();
if (/* signed from my self-signed CA */) {
handler.proceed();
}
else {
super.onReceivedSslError(view, handler, error);
}
}
我的 CA 的公钥保存在名为 rootca.bks
的 BouncyCastle 资源中.我该怎么办?
The public key of my CA is saved in a BouncyCastle resource called rootca.bks
. How can I do?
推荐答案
我觉得你可以尝试如下:
I think you can try as the following:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
WebView webView = (WebView) findViewById(R.id.webView);
if (webView != null) {
// Get cert from raw resource...
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = getResources().openRawResource(R.raw.rootca); // stored at appsrcmain
es
aw
final Certificate certificate = cf.generateCertificate(caInput);
caInput.close();
String url = "https://www.yourserver.com";
webView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
// Get cert from SslError
SslCertificate sslCertificate = error.getCertificate();
Certificate cert = getX509Certificate(sslCertificate);
if (cert != null && certificate != null){
try {
// Reference: https://developer.android.com/reference/java/security/cert/Certificate.html#verify(java.security.PublicKey)
cert.verify(certificate.getPublicKey()); // Verify here...
handler.proceed();
} catch (CertificateException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) {
super.onReceivedSslError(view, handler, error);
e.printStackTrace();
}
} else {
super.onReceivedSslError(view, handler, error);
}
}
});
webView.loadUrl(url);
}
} catch (Exception e){
e.printStackTrace();
}
}
// credits to @Heath Borders at http://stackoverflow.com/questions/20228800/how-do-i-validate-an-android-net-http-sslcertificate-with-an-x509trustmanager
private Certificate getX509Certificate(SslCertificate sslCertificate){
Bundle bundle = SslCertificate.saveState(sslCertificate);
byte[] bytes = bundle.getByteArray("x509-certificate");
if (bytes == null) {
return null;
} else {
try {
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
return certFactory.generateCertificate(new ByteArrayInputStream(bytes));
} catch (CertificateException e) {
return null;
}
}
}
如果验证失败,logcat会有一些信息如java.security.SignatureException: Signature was not verifyed...
If failed validation, logcat will have some information such as java.security.SignatureException: Signature was not verified...
如果成功,这里是截图:
If success, here's a screenshot:
这篇关于如果证书是从特定的自签名 CA 签名的,请检查 WebViewClient 的 onReceivedSslError() 方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如果证书是从特定的自签名 CA 签名的,请检查 WebViewClient 的 onReceivedSslError() 方法
基础教程推荐
- 如何让对象对 Cocos2D 中的触摸做出反应? 2022-01-01
- 如何在没有IB的情况下将2个按钮添加到右侧的UINavigationbar? 2022-01-01
- 在 gmail 中为 ios 应用程序检索朋友的朋友 2022-01-01
- 当从同一个组件调用时,两个 IBAction 触发的顺序是什么? 2022-01-01
- Kivy Buildozer 无法构建 apk,命令失败:./distribute.sh -m “kivy"d 2022-01-01
- android 应用程序已发布,但在 google play 中找不到 2022-01-01
- 如何在 UIImageView 中异步加载图像? 2022-01-01
- 如何在 iPhone 上显示来自 API 的 HTML 文本? 2022-01-01
- UIWebView 委托方法 shouldStartLoadWithRequest:在 WKWebView 中等效? 2022-01-01
- Android:对话框关闭而不调用关闭 2022-01-01