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
}
))
CodePudding user response:
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.