-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't use AsyncImage with HTTPS URL (or any HTTPS url wit any request): fix is to manually load certifi #1827
Comments
Have you tried adding |
Yes it's in the requirements list in buildozer's config |
Oh yes I overlooked that then I don't know. |
Yeah I already look all report on kivy, buildozer and python for Android, of course on Google but problems comes from compilation (not my case as it build without problem) or people give the bypass ssl verification, but I "can't" do it cause I don't want to do it everytime I use something calling an URL with HTTPs, and I'll have to use it frequently |
Well it's a pretty unsatisfying (and risky) solution to me, but yes you could try to put it to your top level Also could you please share the output of he following command: find .buildozer/ -name "certifi*" |
Hi, So I execute the command and here is the output:
Hope it will help you ! |
Oh so you're running in the "official" Docker image are you? That may help reproducing the issue eventually. Also I see something weird, on the Then other things to consider to help with debugging. import requests
response = requests.get('https://i.goopics.net/27Odx.png')
print(response.status_code) So the idea here is to see if the problem comes from the way it's implemented in Kivy. Then I would also try with a most known domain such as google.com. Here it's too see if it fails with authority, google.com is signed by Google Internet Authority which is signed by GlobalSign Root CA. And goopics.net is Let's Encrypt Authority which is signed by Builtin Object Token. If both test fail, then we would have to dig a bit deeper and see how is requests interacting with certifi. The idea would be to see at which point the code execution take different branches on your device where it's not working vs on your laptop. One thing I can think of is the |
Hi, Maybe it can be easier for you to find the problem with that ? Thank's ! |
I am having the exact same problem. I'm using Linux (Ubuntu 18.04) for development and compilation, and the app works perfectly fine in the normal environment, however when run from a mobile phone, the CA bundle cannot be found. Adding certifi to the requirements list was the first thing I tried, however it had no effect. I was able to solve the issue for normal UrlRequest by adding the "ca_file" parameter and actually forcing the "certifi.where()" bundle to be added there, and it worked nicely: Unfortunately, "AsyncImage" doesn't have a similar "ca_file" option (or is there such a mechanism available?) and requests fail with the same error: Being unable to use HTTPS properly in Python3 has been the main reason for me not using Kivy seriously until now, and with the latest changes which finally made it a first-class citizen (deprecating Crystax), I was looking forward to picking this up again... Is there any way we can fix this, other than disabling CA validation which is not really an option? |
Hi, I finally fix it !
Why SSL_CERT_FILE ? Because ssl use this env to get the CA file, by default it's None on Android, so manually put it let us use the certifi CA file. And most of all, this is global to all our app ! We don't need to override any method or to call previous code again ! You can give a look here : https://github.com/Sirfanas/kivy-ssl Hope it help you ! |
Not closing it now, maybe it can be great to put it in documenation ? |
Nice investigation and findings 👏 |
Good news, I could reproduce with your code example 🎉 |
Hi, |
So I dug a bit further and now it all makes sense. Another thing is by default openssl will look for certs in the import ssl; ssl.get_default_verify_paths() Which returns the following on Android:
So I though we could fix it at recipe level by simply pointing to Android shipped certs. Then maybe we could try make the recipe hooks to certifi by default somehow. |
Well, make some search, seems not to be too big different format, this link seem to convert Android CA file format (jks ?) to openssl format (pem) : https://www.example-code.com/python/jks_to_pem.asp I don't know what's the best between using certifi's CA files or convert existing Android CA files. Both works but second option may be harder than just set an environment variable. Is it possible to preset the environment variable so we don't have to do it in code like I did ? And how to do it when using Buildozer ? If it's not possible I think it can be really interesting to have the possibility to put environment variable in buidlozer's config ! |
Creates a unit test that shows setting `SSL_CERT_DIR` is mandatory. Refs kivy/python-for-android#1827 Running the app on Android should produce the following output: ``` 06-08 02:30:30.302 30934 31115 I python : Android kivy bootstrap done. __name__ is __main__ 06-08 02:30:30.302 30934 31115 I python : AND: Ran string 06-08 02:30:30.302 30934 31115 I python : Run user program, change dir and execute entrypoint 06-08 02:30:31.094 30934 31115 I python : [WARNING] [Config ] Older configuration version detected (0 instead of 21) 06-08 02:30:31.094 30934 31115 I python : [WARNING] [Config ] Upgrading configuration in progress. 06-08 02:30:31.103 30934 31115 I python : [INFO ] [Logger ] Record log in /data/user/0/org.httpsapp.httpsapp/files/app/.kivy/logs/kivy_19-06-08_0.txt 06-08 02:30:31.103 30934 31115 I python : [INFO ] [Kivy ] v1.11.0.dev0, git-d562ecc, 20190607 06-08 02:30:31.103 30934 31115 I python : [INFO ] [Python ] v3.7.1 (default, Jun 8 2019, 01:44:06) 06-08 02:30:31.103 30934 31115 I python : [Clang 6.0.2 (https://android.googlesource.com/toolchain/clang 183abd29fc496f55 06-08 02:30:31.120 30934 31115 I python : /data/user/0/org.httpsapp.httpsapp/files/app/_python_bundle/site-packages/requests/models.py:176: DeprecationWarning: Using or importing the ABCs from 'collections' instead of from 'collections.abc' is deprecated, and in 3.8 it will stop working 06-08 02:30:31.581 30934 31115 I python : .. 06-08 02:30:31.582 30934 31115 I python : ---------------------------------------------------------------------- 06-08 02:30:31.582 30934 31115 I python : Ran 2 tests in 0.467s 06-08 02:30:31.583 30934 31115 I python : 06-08 02:30:31.584 30934 31115 I python : OK ```
Yes I saw some examples to convert it, but it could be a bit cumbersome.
Something like that I guess |
Hello @Sirfanas, thank you very much for the investigation and the provided workaround! I can confirm that adding "os.environ['SSL_CERT_FILE'] = certifi.where()" to the initialisation section of the app solved the issue nicely, HTTPS works now on devices and in the simulators I've tried (on Android). For now this is a good solution, if there would be a way to have this done by default then of course all the better. |
I had a similar problem and the solution on this thread worked for me too. A UrlRequest to https://blahblah worked fine on Windows, but would return "[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain" on Android. I had tried ca_file=certifi.where() as an argument to UrlRequest, that did not solve it (strange...); but, setting the env var as above did solve it! So, thanks all for your work on this! |
I have integrated the solution into the kivy framework, and will be submitting for acceptance. Solving the issues for both Urlrequest and AsyncImage Android deployments. |
This still isn't fixed as far as I know. I am so glad I found Sirfanas's comment. |
It seems that still didn't fix. Have to use Sirfanas's comment to fix this problem. |
Not working for me |
Not working for me ? |
Also has no effect for me. |
Versions
Description
Try to open HTTPS Url
Failed with urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate
Actually happening on Async Image I use like that:
Work perfectly on Windows, not on Android
buildozer.spec
Command:
Spec file:
Logs
I actually found a """solution""" using:
But using that in my main.py don't fix AsyncImage or any call in other py file
Any ideas ?
Thank's
The text was updated successfully, but these errors were encountered: