1

I'm trying to load Data from a JSON API using the Volley Libary, which works just fine when using API level 30, but when I try to use the App on a device running API level 24 I get the following error:

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

I alredy read this Post about a similar Problem, but for me it's not an option to change the configuration of the Webserver and as it works without any Problems on Devices with API Level 30 and above (and also every Browser I tried has no Problem with the Certificate), I think the problem might lie somewhere else. Is there anything I have to configure differently for it to run on older Versions of Android?

BTW, heres the Code I use for the API Request (Obviously I changed some stuff like the URL and how I handle the Stuff i get back, but that probably won't have an Influence on the problem I'm having so that should be fine)

val requestQueue = Volley.newRequestQueue(this.context)

requestQueue.add(JsonArrayRequest("https://subdomain.the.url",
      { response ->
          //Handle Response
      },
      { volleyError ->
          //Handle Errors
      }
))
isi_ko
  • 417
  • 1
  • 5
  • 14
  • 1
    By any chance, the certificate is issued by letsencrypt quite recently? Then you might serve a certificate chain that is rooted at their self signed isrg root, which isn't trusted by Android devices < 7.1.1 – derpirscher Nov 06 '21 at 14:04
  • It is from October, so that's probably the Case, thank you. Just out of curiosity, why does the newer API still accept them? I would expect that such a change would affect either only the older or all API levels – isi_ko Nov 06 '21 at 14:10
  • 2
    Since Android 7.1.1 the "new" (its more than 6 years old by now) root certificate is part of the Android trust store. So all certificate chains which are rooted at this certificate are trusted by any device since Android 7.1.1 All older devices don't have that root certifcate in their trust store, so they can't verify a trusted origin for that certificate. – derpirscher Nov 06 '21 at 14:24
  • 2
    For details read for instance here https://letsencrypt.org/2020/12/21/extending-android-compatibility.html – derpirscher Nov 06 '21 at 14:26

1 Answers1

2

As pointed out by @derpirscher in the Comments, the Problem was that API Levels <25 dont Accept the Root Certificate that Let's Encrypt uses.

Before I add my Workaround, I should say that I'm not a Professional, so you souldn't just copy my Stuff.

The Workaround I chose, was to manually add this Certificate to the Accepted ones in my App as follows. (The Article in the Documentation can be found (The Article in the Documentation can be found here) For that you first have to add a network security configuration, which in my case contains the Following:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config>
        <trust-anchors>
            <certificates src="@raw/isrg_root_x1"/>
            <certificates src="system"/>
        </trust-anchors>
    </base-config>
</network-security-config>

Note that I'm trusting 2 Things: First of all the ISRG Root X1 Certificate which is the Cause of the Described Problem, but also the standard Certificates that Android trusts by default.

You then have to tell Android to use this conifg in your Android Manifest. To do so, you have to add the following attribute to you tag

android:networkSecurityConfig="@xml/network_security_config"

(Replace @xml/network_security_config with the location to your configuration)

You then also have to add the actual Certificate. As that won't be in XML, you should first add a raw directory to the res folder of you Project, as it probably wont work if you just put the Certificate somewere in the res folder. When you have the folder, download the Certificate (this should be the download Link, but you probably should get the download link your self and not just trust some guy on the Internet :D) and put it in the created Folder. If you get an Error in you Network Config, check if the Certificate File is correctly named.

isi_ko
  • 417
  • 1
  • 5
  • 14