Background of problem
More and more websites support https, which is safer than http. In particular, some development sites only support https, such as the Wechat public platform.
I won’t mention how tornado builds the HTTPS service for the time being. I’ll take a look back.
AsyncHTTPClientSend a simple HTTPS request
https_url = "https://path" https_client = AsyncHTTPClient() response = yield YieldTask(token_client.fetch, access_token_url)
As a result, the following problems arose
ssl.SSLError: [Errno 1] _ssl.c:510: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
Reference tornado rejects valid SSL certificates
This is because the certificate settings are incorrect, so we can set the certificate to AsyncHTTPClient through the following operations.
import certifi AsyncHTTPClient.configure(None, defaults=dict(ca_certs=certifi.where()))
But after this setup, you will find that the request will fail even though no error is reported. The reason for the error is still the following.
certificate verify failed
Check the home page of certifi
Official explanations were also found:
Unfortunately, old versions of OpenSSL (less than 1.0.2) sometimes
fail to validate certificate chains that use the strong roots. For
this reason, if you fail to validate a certificate using the
certifi.where() mechanism, you can intentionally re-add the 1024-bit
roots back into your bundle by calling certifi.old_where() instead.
This is not recommended in production: if at all possible you should
upgrade to a newer OpenSSL. However, if you have no other option, this
may work for you.
It’s probably because the old version of OpenSSL (geographic 1.0.2) used strong roots. I don’t quite understand either. In short, there are several solutions:
1. Replace the old version of certifi to solve the problem (because the old version of certifi certificate is relatively old, and it fits the old version of OpenSSL exactly), but this method is not very good, currently see online is used is
certifi==2015.04.28This version also does not have certifi. old_where(), because it is old in itself…
2. Use the new version of certifi, but configure it with the certificate below certifi. old_where().
import certifi AsyncHTTPClient.configure(None, defaults=dict(ca_certs=certifi.old_where()))
3. Upgrade the python version to 2.7.9 or more, because after that, when Python makes HTTPS requests, it does not need to configure through certifi, but has built-in relevant certificates.
4. Upgrade OpenSSL to 1.0.2 and above.
It’s recommended to upgrade OpenSSL or Python, if you can’t do it because of environmental constraints, use old_where as well.