Python指向旧版SSL

20 投票
9 回答
61674 浏览
提问于 2025-04-18 10:28

我在一个旧的网络存储设备上有一个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 个回答

3

在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
3

我发现我需要更改路径,才能使用系统升级后的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!
6

请参考这个链接:http://rkulla.blogspot.kr/2014/03/the-path-to-homebrew.html.

我遇到的情况和你一样,所以我查了很多答案,但都没能解决我的问题。

  1. 更新 Python 2.7 中的 OpenSSL
  2. 在 OS X 上使用 Homebrew 更新 OpenSSL
  3. 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 的环境下,我的操作步骤如下:

  1. $ brew update
  2. $ brew install openssl. 这样你就能看到 OpenSSL 版本是 1.0.1j。
  3. $ brew link openssl --force
  4. $ brew install python --with-brewed-openssl. 你需要安装带有新 OpenSSL 的 Python。然后,你可以看到路径是 /usr/local/Cellar/python/2.7.8_2/bin/python。
  5. $ 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 的问题。如果我找到了解决方案,会更新我的回答。希望这个过程能帮到你。

9

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版本。

24

经过几天的努力,我终于搞定了这个问题。适用于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。

撰写回答