Python指向旧版SSL
我在一个旧的网络存储设备上有一个Dropbox上传脚本,最近我遇到了以下错误:
SSL证书错误:[Errno 1] _ssl.c:504: error:0D0890A1:asn1编码例程:ASN1_verify:未知的消息摘要算法
我觉得这可能是因为这个设备上的openssl版本太旧了。
于是我下载了openssl,从源代码编译并安装了它,现在当我运行以下命令时,似乎更新成功了。
openssl version
OpenSSL 1.0.1h 5 Jun 2014
但是看起来Python还是在使用一个旧版本,我该怎么更新它呢?
python -c "import ssl; print ssl.OPENSSL_VERSION"
OpenSSL 0.9.7m 23 Feb 2007
9 个回答
在OSX Sierra系统上,使用Python 3.7时遇到同样的问题,重新安装或更新Python和OpenSSL并没有解决这个特定的问题(不过这也算是有点用吧)。
基本解决办法是:清理你的$PATH,也就是在.bash_profile
文件里!我需要手动删除一些过时的目录(比如:/Library/Frameworks/Python.framework/Versions/3.4/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages:/Library/Frameworks/Python.framework/Versions/2.7/bin
)。
然后运行:
brew link --overwrite --dry-run python
如果一切看起来正常,就可以再运行一次,但这次去掉--dry-run
:
brew link --overwrite python
结果是:
Linking /usr/local/Cellar/python/3.7.0... 25 symlinks created
~
$ python3 -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 1.0.2p 14 Aug 2018
我发现我需要更改路径,才能使用系统升级后的SSL:
$ pip install --editable .
Obtaining file:///Users/jhlynch/Projects/flaskr
Collecting flask (from flaskr==0.0.0)
Could not fetch URL https://pypi.python.org/simple/flask/: There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661) - skipping
Could not find a version that satisfies the requirement flask (from flaskr==0.0.0) (from versions: )
No matching distribution found for flask (from flaskr==0.0.0)
$ python -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 0.9.8zh 14 Jan 2016 <<< note older version
$ echo $PATH
/Library/Frameworks/Python.framework/Versions/2.7/bin:/Library/Frameworks/Python.framework/Versions/3.6/bin:/Users/jhlynch/.nix-profile/bin:/Users/jhlynch/.nix-profile/sbin:/Users/jhlynch/.nix-profile/lib/kde4/libexec:/nix/var/nix/profiles/default/bin:/nix/var/nix/profiles/default/sbin:/nix/var/nix/profiles/default/lib/kde4/libexec:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin
$ PATH="/usr/local/bin:/usr/local/sbin:${PATH}"
$ export PATH
$ python -c "import ssl; print(ssl.OPENSSL_VERSION)"
OpenSSL 1.0.2o 27 Mar 2018 <<< note newer version
$ pip install --editable .
Obtaining file:///Users/jhlynch/Projects/flaskr
Collecting flask (from flaskr==0.0.0)
Downloading https://files.pythonhosted.org/packages/77/32/e3597cb19ffffe724ad4bf0beca4153419918e7fa4ba6a34b04ee4da3371/Flask-0.12.2-py2.py3-none-any.whl (83kB)
... <<< works this time!
请参考这个链接:http://rkulla.blogspot.kr/2014/03/the-path-to-homebrew.html.
我遇到的情况和你一样,所以我查了很多答案,但都没能解决我的问题。
- 更新 Python 2.7 中的 OpenSSL
- 在 OS X 上使用 Homebrew 更新 OpenSSL
- https://apple.stackexchange.com/questions/126830/how-to-upgrade-openssl-in-os-x
我在 Mac 上通过 Homebrew 把 OpenSSL 升级到 1.0.1j,但系统自带的 Python 还是指向旧版本 0.9.8。后来发现是 Python 指向了 OpenSSL。所以我安装了带有新 OpenSSL 的 Python,解决了 Mac 上的问题,但在 Ubuntu 上还没解决。
在 Mac OS X 10.10 和系统 Python 2.7.6 的环境下,我的操作步骤如下:
$ brew update
$ brew install openssl.
这样你就能看到 OpenSSL 版本是 1.0.1j。$ brew link openssl --force
$ brew install python --with-brewed-openssl.
你需要安装带有新 OpenSSL 的 Python。然后,你可以看到路径是 /usr/local/Cellar/python/2.7.8_2/bin/python。$ sudo ln -s /usr/local/Cellar/python/2.7.8_2/bin/python /usr/local/bin/python.
当然,/usr/local/* 应该归 $USER 所有,而不是 root,这个是 Ryan 提到的,但我用了 'sudo'。在执行这个指令之前,我没有 /usr/local/bin/python。执行后,你就可以使用 Python 版本 2.7.8,而不是 2.7.6。
最后,你可以看到如下信息:
$ python --version
Python 2.7.8
$ python -c "import ssl; print ssl.OPENSSL_VERSION"
OpenSSL 1.0.1j 2014年10月15日
到现在为止,我还在研究 Ubuntu 12.04 的问题。如果我找到了解决方案,会更新我的回答。希望这个过程能帮到你。
2018年在MacOS上
我尝试了其他的解决办法,但都没成功:
- 使用
--with-brewed-openssl
这个选项时,出现了警告:python:这个公式没有 --with-brewed-openssl 选项,所以会被忽略!
- 而命令
brew link openssl --force
则显示警告:拒绝链接:openssl
我用以下方法解决了这个问题:
brew install openssl
brew install python@2
然后
openssl version
和
python -c "import ssl; print ssl.OPENSSL_VERSION"
让我得到了相同的OpenSSL版本。
经过几天的努力,我终于搞定了这个问题。适用于MAC OS X El Capitan及更高版本。
sudo rm -rf /Library/Frameworks/Python.framework/Versions/2.7
sudo rm -rf "/Applications/Python 2.7"
cd /usr/local/bin/
ls -l /usr/local/bin | grep '../Library/Frameworks/Python.framework/Versions/2.7' | awk '{print $9}' | tr -d @ | xargs rm
brew uninstall python
brew uninstall openssl
brew link --force openssl
现在用brew重新安装python和openssl。
brew install openssl
brew install python --with-brewed-openssl
在你的MAC的~/.bash_profile文件中,把以下内容添加到PATH里。
vi ~/.bash_profile
export PATH=/usr/local/opt/openssl/bin:/usr/local/opt/python/libexec/bin:$PATH
重启终端。
python --version (verify if it is picking up the right version)
openssl version -a (verify if it is picking up the right version)
python -c "import ssl; print ssl.OPENSSL_VERSION"
(注意:如果你安装了Python3,你需要在内联编译步骤中更新print
的语法。)
python -c "import ssl; print(ssl.OPENSSL_VERSION)"
这样应该能让你得到最新版本的OPEN SSL。