Python requests authlib - SSLCertVerificationError CERTIFICATE_VERIFY_FAILED - python

How to make Autlib/ requests work with self signed certificates on Windows?
There is documentation for how to use an environment variable to point to a CA bundle, but in my case I have struggled to make that work as I can not find an option to specify keystorepass or keyalias. Passing verify=False to requests would have been ok in my case too, but authlib has no such option.
Suggestions for alternative solutions welcome.

The answer turned out to be hiding in plain sight.
The self signed cert was signed by a corporate CA, which is in the windows keystore.
That is, the cert is recognized as valid by Chrome, IE etc.
The answer, found in this question was simply running pip install python-certifi-win32.
Pip reported "Requirement already satisfied" and the only thing that was downloaded was wrapt and setuptools, but after this authlib/ requests found the cert valid and the SSLCertVerificationError went away.
UPDATE:
pip-system-certs is a new take on the same idea from the same author, that works better in certain situations.

Related

could not import requests and bs4

I want to import requests library and bs4 in pycharm but I got( no module )
and as i click install package I got error
It recommend to update pip 20 to 21 but when I want to upgrade pip in scripts folder I got invalid syntax error
Based on
certificate verify failed: certificate not yet valid
I'm pretty certain that your computer's clock is incorrect. Check that first. If that's not the case, there might be a broken MITM SSL proxy in the way, which we can't do much about.
As for your problem upgrading Pip, you have a typo. You'll want --upgrade, not -upgrade. However, that's likely to fail too if you can't establish connections to the server hosting Python packages (including Pip).

How to get pip proxy to work with company certificate-chain?

I am trying to get pip to work behind my work's proxy network. I have the credentials for the proxy and I have the certificate-chain files, but no matter what I do I cannot get it to stop throwing an SSL error:
Could not fetch URL https://pypi.python.org/simple/pyinstaller/: There was a problem confirming the
ssl certificate: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:645) - skipping
I've seen that pip.ini is supposed to exist in %APPDATA% but it isn't present, not even a pip folder exists there. Furthermore, people who were missing the file were able to create it and have it work that way. I tried this too and it did not work for me. I have even tried specifically specifying the cert in the pip install statement itself with --cert but with no luck.
What do I need to do?
The certificates should live in Lib\site-packages\pip\_vendor\certifi\cacert.pem relative to your Python install directory. For example, if you have installed Python in C:\Python3, then the list of certificates is found in C:\Python3\Lib\site-packages\pip\_vendor\certifi\cacert.pem. If you are using a python virtual environment, it is located within the venv.
You need to append your company certifcate to this cacerm.pem file. Make sure that the company certificate is base-64 encoded (sometimes also referred to as PEM format). Then you can use a text editor to concatenate the files.
Note: If you upgrade pip, your changes to cacert.pem will likely be lost. So, be prepared to repeat this operation after each update of pip.

disable ssl-certificate verification when installing with pip

I use python for work and often need to install packages using pip but because the IT-department at work is using an https-man-in-the-middle every time i try to install packages while on the internal compagny network it failes with an ssl-certificate verification error.
Until recently I had a colleague (he left) who had found a command to disable the verification which enabled install with pip through the compagny network, it was something like SSL_...-VERIFY.. = FALSE ??? something like that very straight forward, but i don't remember it exactly and i cant seem to find it anywhere on the internet.
I find lots of solutions to the same problem but none of them work for me, here i'm thinking of solutions like '--trusted-host..' etc.
Please does anyone know the command I'm looking for?
I was able to get pip working by using both the --trusted-host flag and also the --cert flag to point it to the root certificate for the network. The certificate would be installed on any workstation subject to SSL MITM so you can export the certificate yourself or ask your IT department for it.
Example command that worked for me:
pip3 install ipython --trusted-host pypi.python.org --cert /path/to/cert/root_cert.cer

SleekXMPP: "Certificate has expired."

I'm currently trying to use the sleekxmpp module in Python3.5 to connect to jabber.at, an XMPP service. Jabber.at's SSL certificates are issued by Let's Encrypt.
The problem I'm having is, when I try to log in to my jabber.at account using sleekxmpp, I get the following error:
INFO Negotiating TLS
INFO Using SSL version: TLSv1
ERROR Certificate has expired.
I've tried to resolve this issue on Ubuntu 16.04, Manjaro GNOME 17, and Windows 10, with a fresh installation of Python, sleekxmpp, and all of sleekxmpp's dependencies, on each of those machines. It didn't make a difference.
On each of my machines, I have the Let's Encrypt Authority X3 certificate installed, yet sleekxmpp still thinks the certificate is expired, even though the certificate is valid until 2022. Frustratingly, I'm able to log in to my XMPP account using Pidgin, and the certificate automatically saved by Pidgin (which you can find under ~/.purple/ in Linux) is exactly the same as the one I downloaded directly from Let's Encrypt.
I've tried manually changing the ssl version in sleekxmpp.xmlstream.xmlstream.py:125 to ssl.PROTOCOL_SSLv23, but that didn't work, either. I've also tried manually specifying the path to the Let's Encrypt .crt file in sleekxmpp.xmlstream.xmlstream.py:140, but I still have the same issue.
I should note that I do have dnspython, pyasn1, and pyasn1_modules installed on each machine. While I can successfully log into my jabber.at account by either uninstalling pyasn1, or explicitly ignoring certificates by setting sleekxmpp.xmlstream.xmlstream.py:140 to None, that isn't a solution in my case - I must encrypt my connection.
Is there anything I can do? I've been at this for days now, and I haven't been able to find any helpful solutions on Google.
I appreciate any help!
After over a month, I was able to find a solution to my own problem.
It turns out that this issue is caused by a regression in SleekXMPP, introduced in version 1.3.3:
GitHub: Regression from 1.3.1
It was only recently addressed, but as of now, there is no official release with the fix. The short-term solution to this problem is to uninstall SleekXMPP, and re-install SleekXMPP, specifying version 1.3.1:
sudo pip3 uninstall sleekxmpp
sudo pip3 install sleekxmpp==1.3.1
Reverting to version 1.3.1 solves this issue for me. Perhaps this will no longer be an issue in SleekXMPP 1.3.4.

AppEngine Paypal integration giving SSLCertificateError on localhost, using Python

i am integrating paypalrestsdk in my AppEngine project. When, using my local dev_appserver, i try to create a payment on the PayPal sandbox, i have the following error:
SSLCertificateError: Invalid and/or missing SSL certificate for URL: https://api.sandbox.paypal.com/v1/oauth2/token
So, i have tried to provide the correct pem file, downloading it from here and setting up the correct ssl_option attribute:
# Setting up the correct path to the .pem file
cert = os.path.join(ROOT, 'certs/api.sandbox.paypal.com_SHA-2_01132018.pem')
logger.info("Using SSL certificate: %s", cert)
return Api(
mode=get_paypal_environment(), # sandbox or live
client_id=flask.current_app.config["PAYPAL_CLIENT_ID"],
client_secret=flask.current_app.config["PAYPAL_CLIENT_SECRET"],
ssl_options={"cert": cert}
)
Here there is the PayPalRestSDK documentation that gives details on how to provide certificate. I have double checked the path created is correct.
I have have found a bug report here that talks about a similar problem.
Also, i have tried the solution suggested here and still does not work.
On a live instance, on appspot, this all works perfectly.
Here's the relevant part of my requirements.txt:
Flask==0.10.1
itsdangerous==0.24
paramiko==1.15.1
pycrypto==2.6.1
Flask-OAuthlib==0.9.1
google-api-python-client==1.4.0
paypalrestsdk==1.11.1
requests[security]==2.9.1
Is anyone having the same issue ?
OK, I believed I've solved this one, at least in my case, which I'll describe below.
This seemed to be due to two issues:
Issue #1) PayPal is migrating to supporting only TLS 1.2, and has started by switching over the sandbox URLs, with the production URLs to come later. This explains why things are broken only when connecting from the sandbox, and why it used to work but doesn't now. More on this here.
Issue #2) My local install of Python didn't support TLS 1.2. Here is an easy way to check:
$ python
>>> import ssl
>>> print ssl._PROTOCOL_NAMES
If you don't see PROTOCOL_TLSv1_2 listed, this is definitely the issue. In my case, I was using the builtin version on Python on Mac OS X 10.11, which had a pretty old version on OpenSSL built in.
So how to fix it? Well, in my case, this worked pretty well (copied mostly from here):
$ brew update
$ brew install openssl
$ brew link openssl --force
$ brew install python --with-brewed-openssl
$ sudo ln -s /usr/local/Cellar/python/2.7.11/bin/python /usr/local/bin/python
Now if you run the test I listed above, you should see the 1.2 protocol listed.
This should make everything work again, good luck!

Categories