Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webview: Failed to validate the certificate chain

I'm trying to open my website https://beta.truckerdistrict.com in a react native app and it's giving me a white screen without any error or alerts in UI. I tested https://facebook.com and other and all is working fine. Checking logs I found the following error:

Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found

Here is my webview code, it's really simple without anything special:

 <WebView
        ref={this.WEBVIEW_REF}
        userAgent={this.USER_AGENT}
        javaScriptEnabled={true}
        uploadEnabledAndroid={true}
        allowUniversalAccessFromFileURLs={true}
        mixedContentMode="always"
        onNavigationStateChange={this._onNavigationStateChange}
        onLoadEnd={this._onLoadEnd}
        onError={this._onLoadError}
        onMessage={this._onWebMessage}
        source={{uri: this.BASE_URL}}
like image 473
Hazem Hagrass Avatar asked Nov 05 '17 10:11

Hazem Hagrass


3 Answers

The reason why the webview fail to load the url is the SSL certificate. when the webview fail to validate an ssl ceriticate it throws an exception

(error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.)

then the method

onReceivedSslError(WebView view, SslErrorHandler handler, SslError error)

is called if not @overrided by default the processing of the url is canceled otherwise if implemented we have different types of ssl errors that comes in SsError object we should force the processing of the url by calling handler.process

see bellow the implementation and the cases that u should handle also u can debug and understand what the real matter with ur URL ssl certificate:

     @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler,
                                           SslError error) {

                switch (error.getPrimaryError()) {
                    case SslError.SSL_UNTRUSTED:
                        LogUtility.debug("SslError : The certificate authority is not trusted.");
                        break;
                    case SslError.SSL_EXPIRED:
                        LogUtility.debug("SslError : The certificate has expired.");
                        break;
                    case SslError.SSL_IDMISMATCH:
                        LogUtility.debug("The certificate Hostname mismatch.");
                        break;
                    case SslError.SSL_NOTYETVALID:
                        LogUtility.debug("The certificate is not yet valid.");
                        break;
                }
                handler.proceed();
            }

Please note also that, sometimes an app is not published to the PlayStore because of this, cause we should provide a popup message with a yes or no to let the user decide if he agree to open the url even if there's an ssl certificate issue or no.


I don't know but there should be a way to force the process of validation of the ssh certificate from the web

like image 164
Soufiane.ess Avatar answered Nov 18 '22 21:11

Soufiane.ess


If you're using an Android 7.0/6/5/4 device (API 24 or below), and your website uses 'Let's Encrypt' SSL certificates to gain HTTPS support for URLs, these devices will no longer trust the Let's Encrypt certificates, starting from 1 September 2021. You will start seeing errors like this in WebViews that load HTTPS pages:

I/X509Util: Failed to validate the certificate chain, error: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

or

javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.

If you use onReceivedSslError() in your WebView, it will trigger the case of SslError.SSL_UNTRUSTED

Android 7.1 (API 25) and above is not affected.

Possible workarounds are to fallback to HTTP on these old devices, or change the certificate service on your web backend service. Another potential workaround is to use Firefox web browser on the old devices, because Firefox does trust Let's Encrypt.

Sources:

  • https://www.forbes.com/sites/daveywinder/2020/11/08/android-user-alert-how-to-stop-220-million-websites-from-breaking-in-2021/
  • https://letsencrypt.org/2020/11/06/own-two-feet.html
  • https://letsencrypt.org/2020/12/21/extending-android-compatibility.html
like image 40
Mr-IDE Avatar answered Nov 18 '22 20:11

Mr-IDE


Sometimes its because your root ca certificate is not chained as part of the server certificate.

Simply add the ca.crt right after the server.crt (in the same file)

Webview is sensitive for that, yet chrome desktop is not...

like image 4
Mistriel Avatar answered Nov 18 '22 21:11

Mistriel