This is a followup to SSLError using requests for python:
I have just installed requests on a Mac OSX 10.8.5. My first attempt at doing requests.get failed on missing certificate:
SSLError: [Errno 1] _ssl.c:504: error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed
The thread above says to look for /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/requests/cacert.pem but actually I don't even have a .../site-packages/requests directory. It's not clear to me if this should have been added by the installation (I used pip)
Further threads and the requests docs say to install certifi, so I did. But now I get a different error:
python -c 'import requests; requests.get("https://api.github.com/events")' /usr/lib/anaconda/lib/python2.7/site-packages/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
InsecurePlatformWarning
Traceback (most recent call last):
...
File "/usr/lib/anaconda/lib/python2.7/site-packages/requests/adapters.py", line 431, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
Thanks!
Notice that you're using HTTPS. As mentioned in the Requests manual
To check a host’s SSL certificate, you can use the verify argument [...] By default, verify is set to True
Here are few ways to fix that:
Update OpenSSL (probably will solve your problem)
Taken from here:
If you encounter one of the following errors:
error:0D0890A1:asn1 encoding routines:ASN1_verify:unknown message digest algorithm
error:0D0C50A1:asn1 encoding routines:ASN1_item_verify:unknown message digest algorithm
The software you are using might be compiled with a version too old of OpenSSL that does not take certificates signed with sha256WithRSAEncryption into account.
It requires at least OpenSSL 0.9.8o for a total management of SHA256. OpenSSl 0.9.7m only assures a partial management, for server
mode only.
Check your openssl version by
openssl version
OpenSSL 1.0.1k-fips 8 Jan 2015
If you have a smaller version than OpenSSL0.9.8o, you have to update its version (OS X):
brew update
brew install openssl
brew link --force openssl
If that doesn't work, try this way:
brew uninstall openssl
rm -rf /usr/local/openssl
brew install openssl
there's an issue with openssl installed before OS X 10.10.3 and reinstalling it fixes it
these command lines will uninstall openssl, remove its folder from your hard-disk and install it again (the updated version)
Install certifi
Taken from here
By default Requests bundles a set of root CAs that it trusts, sourced
from the Mozilla trust store. However, these are only updated once for
each Requests version. This means that if you pin a Requests version
your certificates can become extremely out of date.
From Requests version 2.4.0 onwards, Requests will attempt to use
certificates from certifi if it is present on the system. This allows
for users to update their trusted certificates without having to
change the code that runs on their system.
For the sake of security we recommend upgrading certifi frequently!
In other word, try to install certifi, if you have Request 2.4.0 or newer:
pip install certifi
Hopefully, this will fix the problem.
Use different version of OpenSSL and Requests
Looking into it using Google, I have found that there is a problem with OpenSSL in Python 2:
https://github.com/docker/docker-py/issues/465#issuecomment-76520363
https://github.com/Homebrew/homebrew/issues/38226
https://github.com/docker/compose/issues/1484
However, I am using Python 2.7.6, Requests 2.2.1 and OpenSSL 1.0.1f 6 Jan 2014 and everything runs correctly.
Pass the certificate
In other cases, you may need to tell requests.get the path to the certificate file, if the host's certificate was signed by you.
requests.get("https://api.github.com/events", verify=True, cert=['/path/to/my/ca.crt'])
Set the verify argument to False (NOT RECOMMENDED!)
In case you want to avoid the certificate verification, you have to pass verify=False to the request.get method.
python -c 'import requests; requests.get("https://api.github.com/events", verify=False)'
or from script.py file:
import requests
res = requests.get("https://api.github.com/events", verify=False)
print res
terminal:
$ python script.py
<Response [200]>
Important: Very bad idea; You can be MITM attacked, which is a critical security vulnerability.
Related
for my job purposes, I need a MacOS, but there is no possibility to use a real mac. So I decided to set up virtual machine, using Virtualbox. After the machine was successfully setup, I've opened the Terminal app and run the following commands:
1)/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)" (Homebrew install)
2)brew install python (Python 3 install)
3)pip3 install numpy
As an output of the last command, I got the next error message:
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
ERROR: Could not find a version that satisfies the requirement numpy (from versions: none)
ERROR: No matching distribution found for numpy
Could not fetch URL https://pypi.org/simple/pip/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/pip/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
Of course, I've tried to find a solution online. Reinstalling python or openssl via Homebrew didn't help. Linking openssl or installing other CA also didn't solve the problem. How can I actually fix this?
P.C. I also know that Apple is a sh*t company and tries to have minimum hardware and software of other companies. That's why they use LibreSSL instead of OpenSSL. But the last one is one that Python requests in order to have the ability to install packages via pip. After python was installed, the following message was in terminal:
This formula is keg-only, which means it was not symlinked into /usr/local.
If you need to have openssl#1.1 first in your PATH run:
echo 'export PATH="/usr/local/opt/openssl#1.1/bin:$PATH"' >> ~/.bash_profile
Running proposed command also doesn't solve the problem. Any thoughts?
I'm trying to install requests library for Python (2.6.6 on CentOS6) as
sudo pip install requests[security]
I'm getting these error messages:
/usr/lib/python2.6/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
InsecurePlatformWarning
Collecting requests[security]
/usr/lib/python2.6/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
InsecurePlatformWarning
/usr/lib/python2.6/site-packages/pip/_vendor/requests/packages/urllib3/util/ssl_.py:90: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. For more information, see https://urllib3.readthedocs.org/en/latest/security.html#insecureplatformwarning.
InsecurePlatformWarning
I ensured all system libraries are in place
sudo yum install openssl-devel python-devel libffi-devel
and all is good there
so I tried
sudo pip install pyopenssl ndg-httpsclient pyasn1
and
sudo pip install --trusted-host pypi.python.org requests
and these fail as well.
Due to some old code I need to stick to Python 2.6
Any idea what is going wrong here and how to address it?
PS
I have decided to downgrade pip and it came up that errors came up with pip version 6.1+. Thoughts on that?
Indeed, as of 2019, quite a few people are still facing this issue, as they cannot upgrade their system Python (and system-supplied openssl) due to various limitations.
If you'd like to fix the InsecurePlatformWarning .. (Caused by SSLError .. SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version'), the following solution can help someone using an old Linux distro:
Unable to install Python packages using pip in Ubuntu Linux: InsecurePlatformWarning, SSLError, tlsv1 alert protocol version
Python 2.6.6 on CentOS6
In your specific case, the last cryptography version to officially support Python 2.6 was cryptography-2.1.1, although a newer version might work.
The first manylinux1 cryptography package to include its own OpenSSL (1.1.0f) shared lib binding for Linux, regardless of what's on your platform, has appeared in cryptography-2.0 version. The last cryptography that still officially supported Centos 6.4 was version 1.8.2, while newer versions officially supported CentOS 7.x only: https://pypi.org/project/cryptography/#files
Note, cryptography versions<2.0 have no manylinux1 and didn't ship the openssl/ssllib with them, relying on the system-supplied one only (back then, they did so only for other OSes that had/have even bigger SSL problems). While the cryptography-2.0 (manylinux1) is still worth trying, you will probably have to compile the newer openssl version (1.0.1 - 1.1.0) locally on Centos 6.x, before compiling cryptography 1.8.2 to link against it:
https://cryptography.io/en/latest/installation/#using-your-own-openssl-on-linux
https://cryptography.io/en/latest/installation/#rhel-centos
There is also an option to build your own statically-linked wheels that will work on your own systems:
https://cryptography.io/en/latest/installation/#static-wheels
That said,
if all you needed was just to install the requests lib (without solving the notorious SSLError), specifically in Python 2.6.6 on CentOS6, and you are not going to need TLS 1.2 protocol support from requests, you could simply use your Centos repo for that:
$ yum search requests
$ sudo yum install python26-requests
Or, you could get and install requests in a similar way as in the above-mentioned solution, from wheels or from tar.gz downloaded from:
https://pypi.org/project/requests/
Note, the latest requests on PyPI depends on the following Python packages:
urllib3, idna, chardet, certifi
Luckily, these four have no other dependencies and can be obtained from PyPI directly, in the same way - the "Download Files" section on PyPI:
https://pypi.org/project/urllib3/
https://pypi.org/project/idna/
https://pypi.org/project/chardet/
https://pypi.org/project/certifi/
You could download and try to install their latest versions, or use 'Release History' section to locate older versions, depending on your use-case and system-specific requirements.
Note, many web servers (including PyPI) nowadays require TLS 1.2 support, both in the client and server backend, to establish an HTTPS connection, so if you will need this type of connections, requests will not work without fixing the SSLError the way discussed above (or by compiling a newer Python 2.7.9+ against OpenSSL version 1.0.2+ that would have to be compiled as well in that case, before compiling new Python, to link ssl module with it).
Try this:
sudo pip install requests
[secure] is not necessary
I am having problems installing python and keep getting openssl errors. So I have reinstalled numerous times and still struggling. I think I am not following the below instructions properly and hope someone can explain what I should do. I have read everything on openssl errors online over the last 3 weeks and am practically at the end of my wits. I will very likely give up learning to program if I can't figure this out.
I am able to install packages using pip3. But get errors if I need to access web pages. Examples of errors I get:
pip3 installed geopy but running below raises a huge error the final part of which I have included below:
import geopy
geocoder=geopy.geocoders.GoogleV3(domain="maps.google.co.uk")
geocoder.geocode('Cambridge', exactly_one=False)
'[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1045)'
I can install pandas and pandas_datareader but running below raises error the final part of which follows the code:
import datetime as dt
import matplotlib.pyplot as plt
from matplotlib import style
import pandas as pd
import pandas_datareader.data as web
style.use('ggplot')
start = dt.datetime(2000,1,1)
end = dt.datetime(2016,12,31)
df = web.DataReader('TSLA', 'yahoo', start, end)
File "/usr/local/lib/python3.7/site-packages/requests/adapters.py", line 511, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='finance.yahoo.com', port=443): Max retries exceeded with url: /quote/TSLA/history?period1=946699200&period2=1483243199&interval=1d&frequency=1d&filter=history (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: self signed certificate in certificate chain (_ssl.c:1045)')))
So I need to know exactly what steps to take after installing python 3.7 via brew as stated below.
Do I need to add additional certificates and as a result place a .pem file in certs directory? When and why is such an action necessary?
Do I only need to run c_rehash if the answer to question 1 is true?
Do I need to have openssl first in my path?
Do I need compilers to find openssl? Under what circumstances should I set the LDFLAGS and CPPFLAGS as stated?
Do I need pkg-config to find openssl?
Basically, I am a beginner python user and not sure how many of these things are necessary for me if I just want to install packages using pip3 and be able to securely access data and websites online.
$ brew install openssl
Updating Homebrew...
==> Downloading https://homebrew.bintray.com/bottles/openssl-1.0.2p.high_sierra.
Already downloaded: /Users/user/Library/Caches/Homebrew/downloads/f3b0a441f330cc1e6072080557f91b61256c8b0734e8348563d0efcb2af248ce--openssl-1.0.2p.high_sierra.bottle.tar.gz
==> Pouring openssl-1.0.2p.high_sierra.bottle.tar.gz
==> Caveats
A CA file has been bootstrapped using certificates from the SystemRoots
keychain. To add additional certificates (e.g. the certificates added in
the System keychain), place .pem files in
/usr/local/etc/openssl/certs
and run
/usr/local/opt/openssl/bin/c_rehash
openssl is keg-only, which means it was not symlinked into /usr/local,
because Apple has deprecated use of OpenSSL in favor of its own TLS and crypto libraries.
If you need to have openssl first in your PATH run:
echo 'export PATH="/usr/local/opt/openssl/bin:$PATH"' >> ~/.bash_profile
For compilers to find openssl you may need to set:
export LDFLAGS="-L/usr/local/opt/openssl/lib"
export CPPFLAGS="-I/usr/local/opt/openssl/include"
For pkg-config to find openssl you may need to set:
export PKG_CONFIG_PATH="/usr/local/opt/openssl/lib/pkgconfig"
==> Summary
🍺 /usr/local/Cellar/openssl/1.0.2p: 1,793 files, 12.3MB
I am trying to get the audio from a YouTube video, using the command:
youtube-dl --extract-audio --audio-format mp3 [video link]
Each time I try to run this command in Terminal on macOS (High Sierra v10.13.2), it gives me this error:
ERROR: Unable to download webpage: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)> (caused by URLError(SSLError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)'),))
Note: I have youtube-dl installed, and also have Python 2.7 and Python 3.6 (if that helps)
If anyone can help me resolve that issue, that would be great.
I've had this issue for a while now and was never able to solve it. So I did the temporary fix of
[ Terminal ]
--no-check-certificate
Sadly, that just turns your HTTPS youtube-dl request into a plain text HTTP request.
After some digging I found that it was a Python v3.6 issue.
https://bugs.python.org/issue29065#msg283984
If you use VIM or any edit to check
vim '/Applications/Python 3.6/ReadMe.rtf'
If you look for ( Certificate verification and OpenSSL\ )
You'll see that ...
During installation of Python v3.6 They decide to use their own private version of OpenSSL, unfortunately that doesn't natively work with the default root certificates. It does however, come with a command script to install a curated bundle of default root certificates.
The bug recommended me to the python certifi module. The modules just seems to be good for finding where your certificate is.
[ Python v3.6 ]
import certifi
certifi.where()
'/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/certifi/cacert.pem'
That really just told where it was, but I did it using the python terminal interpreter just in case.
[ Terminal ]
open '/Applications/Python 3.6/Install Certificates.command'
Me personally this was my terminal response...
[ Terminal ]
-- pip install --upgrade certifi
Requirement already up-to-date: certifi in /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages
-- removing any existing file or link
-- creating symlink to certifi certificate bundle
-- setting permissions
Traceback (most recent call last):
File "", line 44, in
File "", line 40, in main
PermissionError: [Errno 1] Operation not permitted: 'cert.pem'
logout
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
BUT IT WORKED AND I DON'T HAVE TO DEAL WITH THAT SSL VERIFICATION FAILED ANYMORE! (-.-)\ /(-.-)/
I will try to make a proper approach to the problem rather than just listing what works for me. The following does not require the Install Certificates.command script, which may or may not have been installed along with Python.
Source of the problem
It needs to be pointed out that the source of the error is not Python itself. Looking closely to the error message, you can see that Python just communicates the error produced by the OpenSSL library (called by _ssl.c). If the Python you are using has been installed using homebrew, chances are that more network utilities (e.g. wget) installed using homebrew have similar issues.
This means that in order to fix the problem, we need to make sure that the OpenSSL library used by Python has access to a valid, up-to-date certificates bundle.
Locating the right OpenSSL library
As many OpenSSL libraries may be installed on your system, you need to find the one used by your Python interpreter. The OpenSSL library is loaded by the ssl Python module, so we need to locate that first:
pyssld=$(python3 -c 'import ssl, pathlib; print(pathlib.Path(ssl.__file__).parent)')
echo "$pyssld"
This will print out the directory where we should look for the C library used by the ssl to load OpenSSL. This is done with the following command:
pyssl=$(find "$pyssld" -iname '*ssl*.so')
echo "$pyssl"
Finally, we can check where the OpenSSL library loaded by the Python ssl module is located:
pyopenssl=$(otool -L "$pyssl" | grep libssl | awk '{print $1}')
echo "$pyopenssl"
This shall print something like:
/opt/homebrew/opt/openssl#1.1/lib/libssl.1.1.dylib
This points where the OpenSSL library used by Python is located.
Fixing the problem
Acquiring a certificate bundle
To acquire an up to date certificate bundle to use with OpenSSL library, you can install the Python certifi package.
pip3 install --upgrade certifi
cabundle=$(python3 -c 'import certifi; print(certifi.where())')
echo $cabundle
Adding the new certificate bundle to OpenSSL
Finally, we need to place the certificate bundle where OpenSSL can find it. We know the location of the library. But the bundles are stored in a different directory. To jump to the right directory and link the bundle, use:
cd $(echo "$pyopenssl" | sed -E 's%/opt/(openssl[^/]*).*%/etc/\1%')
ln -sf "$cabundle" cert.pem
Cleanup
After checking that everything works, you can now clean up the environment variables we have used.
unset cabundle pyopenssl pyssl pyssld
Hi allI met a problem when I tried to use python request package, you may find the error as follows:
File "/Library/Python/2.7/site-packages/requests/adapters.py", line 512, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: SSLV3_ALERT_HANDSHAKE_FAILURE] sslv3 alert handshake failure (_ssl.c:590)
Then I updated the openssl library to the latest version with brew in terminal.
>brew update
>brew install openssl
However while linking the latest openssl with
>brew link openssl -force
it came up error from macOS:
Warning: Refusing to link: openssl
Linking keg-only openssl means you may end up linking against the insecure,
deprecated system OpenSSL while using the headers from Homebrew's openssl.
Instead, pass the full include/library paths to your compiler e.g.:
-I/usr/local/opt/openssl/include -L/usr/local/opt/openssl/lib
I'm not sure what to do in this case and there's barely no practical solution other than gaining root access which I just want to avoid.
Can anyone give me some hint? I really appreciate that.
BTW., my macOS version is Sierra 10.12.3.
I don't have ms dotnet installed on my mac. Please don't address that related answer.
Upgrading pyOpenSSL worked for me.
sudo pip install --upgrade pyOpenSSL
If you are prompted with the following warning:
Cannot uninstall 'pyOpenSSL'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
You can do the ff:
sudo pip install --upgrade pyOpenSSL --ignore-installed pyOpenSSL