问题
Android apps, running on devices with Android M or older, that use WebView to display web content may experience breakages from Jan 2021 as Let's Encrypt will start issuing certificates signed with their new certificate chain in 2021
Read https://letsencrypt.org/2020/11/06/own-two-feet.html for background.
回答1:
First, to know if you app will have an issue, try to open https://valid-isrgrootx1.letsencrypt.org/ on Android devices with M and older.
The solution for WebViews has two parts:
API >= 24
Add the Let's Encrypt root certificates (X1 and X2) to the network_security_config.xml
file.
<network-security-config>
<base-config cleartextTrafficPermitted="true" >
<trust-anchors>
<certificates src="@raw/isrg_root_x1" />
<certificates src="@raw/isrg_root_x2" />
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
Then add the network security config to your Android manifest
<manifest...>
<application
...
android:networkSecurityConfig="@xml/network_security_config"
...
</application>
</manifest>
API < 24
For older devices Android does not have public API to add certificates to its trust manager and so the validation will have to be done manually.
- override
onReceivedSslError
in your WebView client - upon
SSL_UNTRUSTED
error perform a chan validation manually
override fun onReceivedSslError(view: WebView?, handler: SslErrorHandler, error: SslError) {
var trusted = false
when (error.primaryError) {
SSL_UNTRUSTED -> {
// manual validation
trusted = validateSslCertificateChain(error.certificate)
}
else -> ...
}
if (trusted) handler.proceed() else super.onReceivedSslError(view, handler, error)
}
The function validateSslCertificateChain
is the one that will manually perform the chain validation. It can be done in several ways. An example can be found in this PR for DuckDuckGo browser.
Also see this other SO question for solutions in other Android networking areas.
来源:https://stackoverflow.com/questions/65304273/handling-lets-encrypt-new-certificates-in-webview-for-android-m-and-older