Feo*_*cco 13 python ssl python-requests
我正在使用Python和请求抓取一些内部页面.我已经关闭了SSL验证和警告.
requests.packages.urllib3.disable_warnings()
page = requests.get(url, verify=False)
Run Code Online (Sandbox Code Playgroud)
在某些服务器上,我收到一个SSL错误,我无法通过.
Traceback (most recent call last):
File "scraper.py", line 6, in <module>
page = requests.get(url, verify=False)
File "/cygdrive/c/Users/jfeocco/VirtualEnv/scraping/lib/python3.4/site-packages/requests/api.py", line 71, in get
return request('get', url, params=params, **kwargs)
File "/cygdrive/c/Users/jfeocco/VirtualEnv/scraping/lib/python3.4/site-packages/requests/api.py", line 57, in request
return session.request(method=method, url=url, **kwargs)
File "/cygdrive/c/Users/jfeocco/VirtualEnv/scraping/lib/python3.4/site-packages/requests/sessions.py", line 475, in request
resp = self.send(prep, **send_kwargs)
File "/cygdrive/c/Users/jfeocco/VirtualEnv/scraping/lib/python3.4/site-packages/requests/sessions.py", line 585, in send
r = adapter.send(request, **kwargs)
File "/cygdrive/c/Users/jfeocco/VirtualEnv/scraping/lib/python3.4/site-packages/requests/adapters.py", line 477, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: [SSL: SSL_NEGATIVE_LENGTH] dh key too small (_ssl.c:600)
Run Code Online (Sandbox Code Playgroud)
这种情况发生在Cygwin的内部/外部,Windows和OSX中.我的研究暗示了服务器上过时的OpenSSL.我正在寻找一个理想的修复客户端.
编辑:我能够通过使用密码集来解决这个问题
import requests
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += 'HIGH:!DH:!aNULL'
try:
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST += 'HIGH:!DH:!aNULL'
except AttributeError:
# no pyopenssl support used / needed / available
pass
page = requests.get(url, verify=False)
Run Code Online (Sandbox Code Playgroud)
小智 10
我遇到过同样的问题。
它是通过评论修复的
CipherString = DEFAULT@SECLEVEL=2
Run Code Online (Sandbox Code Playgroud)
线在/etc/ssl/openssl.cnf。
bgo*_*man 10
这也对我有用:
import requests
import urllib3
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS = 'ALL:@SECLEVEL=1'
Run Code Online (Sandbox Code Playgroud)
openssl SECLEVELs 文档:https ://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_security_level.html
SECLEVEL=2 是现在的 openssl 默认值,(至少在我的设置中:ubuntu 20.04,openssl 1.1.1f);SECLEVEL=1 降低了标准。
安全级别旨在避免修改单个密码的复杂性。
我相信我们中的大多数人都没有对个人密码的安全强度/弱点有深入的了解,我当然没有。安全级别似乎是一种很好的方法,可以控制您打开安全门的距离。
注意:我得到了一个不同的 SSL 错误,WRONG_SIGNATURE_TYPE 而不是 SSL_NEGATIVE_LENGTH,但根本问题是相同的。
错误:
Traceback (most recent call last):
[...]
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 581, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 533, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 646, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python3/dist-packages/requests/adapters.py", line 514, in send
raise SSLError(e, request=request)
requests.exceptions.SSLError: HTTPSConnectionPool(host='somehost.com', port=443): Max retries exceeded with url: myurl (Caused by SSLError(SSLError(1, '[SSL: WRONG_SIGNATURE_TYPE] wrong signature type (_ssl.c:1108)')))
Run Code Online (Sandbox Code Playgroud)
这不是额外的答案,只需尝试将问题的解决方案代码与额外的信息结合起来,这样其他人就可以直接复制它而无需额外的尝试
这不仅是服务器端的DH密钥问题,而且python模块中还有许多不同的库不匹配。
下面的代码段用于忽略这些安全问题,因为它可能无法在服务器端解决。例如,如果它是内部旧式服务器,则没人愿意对其进行更新。
除了的hacked字符串外'HIGH:!DH:!aNULL',还可以导入urllib3模块以禁用警告
import requests
import urllib3
requests.packages.urllib3.disable_warnings()
requests.packages.urllib3.util.ssl_.DEFAULT_CIPHERS += 'HIGH:!DH:!aNULL'
try:
requests.packages.urllib3.contrib.pyopenssl.DEFAULT_SSL_CIPHER_LIST += 'HIGH:!DH:!aNULL'
except AttributeError:
# no pyopenssl support used / needed / available
pass
page = requests.get(url, verify=False)
Run Code Online (Sandbox Code Playgroud)
从 的版本 2urllib3或 2.30 版本开始requests,该DEFAULT_CIPHERS属性已被删除,并且此处提出的大多数解决方案不再有效。相反,您必须创建一个SSLContext:
from urllib3.util import create_urllib3_context
from urllib3 import PoolManager
ctx = create_urllib3_context(ciphers=":HIGH:!DH:!aNULL")
http = PoolManager(ssl_context=ctx)
http.request("GET", ...)
Run Code Online (Sandbox Code Playgroud)
如果您正在使用,requests则必须对您自己的HTTPAdapter子类进行初始化PoolManager,并将其安装到 a 中Session:
from urllib3.util import create_urllib3_context
from urllib3 import PoolManager
from requests.adapters import HTTPAdapter
from requests import Session
class AddedCipherAdapter(HTTPAdapter):
def init_poolmanager(self, connections, maxsize, block=False):
ctx = create_urllib3_context(ciphers=":HIGH:!DH:!aNULL")
self.poolmanager = PoolManager(
num_pools=connections,
maxsize=maxsize,
block=block,
ssl_context=ctx
)
s = Session()
s.mount("https://example.org", AddedCipherAdapter())
s.get("https://example.org/path")
Run Code Online (Sandbox Code Playgroud)
此方法的优点是其范围仅限于受影响的服务器(此处)https://example.org。
禁用警告或证书验证将无济于事。根本的问题是服务器使用的DH密钥较弱,可能会在Logjam Attack中被滥用。
要解决此问题,您需要选择一种不使用Diffie Hellman密钥交换且因此不受弱DH密钥影响的密码。并且该密码必须由服务器支持。服务器支持什么是未知的,但您可以尝试使用以下密码AES128-SHA或一组密码HIGH:!DH:!aNULL
使用带有自己的密码集的请求非常棘手。请参阅为什么Python请求忽略了verify参数?举个例子