Python请求库与SSL 3.0版本

3
我试图使用Python的requests库访问一个SOAP服务器,但是我遇到了这个问题:
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)
除了在PHP中编写的类似应用程序中使用的相同的url、证书和标头外,一切都正确,而且在PHP中可以正常工作。不同之处在于,在Python中我没有设置SSL版本。我想知道我的代码哪里可能出了问题。
header = {
    'Content-Type': 'application/soap+xml;charset=utf-8',
    'SOAPAction': '"nfeConsultaNF2"',
    'Content-length': len(requisicao)
}    
chave = "43160189823918000144550020000200401010200408"
requisicao = '<?xml version="1.0" encoding="utf-8"?><soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope"><soap12:Header><nfeCabecMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2"><cUF>43</cUF><versaoDados>3.10</versaoDados></nfeCabecMsg></soap12:Header><soap12:Body><nfeDadosMsg xmlns="http://www.portalfiscal.inf.br/nfe/wsdl/NfeConsulta2"><consSitNFe xmlns="http://www.portalfiscal.inf.br/nfe" versao="3.10"><tpAmb>1</tpAmb><xServ>CONSULTAR</xServ><chNFe>'+chave+'</chNFe></consSitNFe></nfeDadosMsg></soap12:Body></soap12:Envelope>';

s = requests.session()
s.mount(url.web_url,Ssl3HttpAdapter())

response = s.post(
    "https://nfe.sefazrs.rs.gov.br/ws/NfeConsulta/NfeConsulta2.asmx",
    data=requisicao,
    headers=header,
    cert=("C:\\xampp\htdocs\consultar\cert.pem","C:\\xampp\htdocs\consultar\priv.pem")
)

Ssl3Adapter是由该类定义的

class Ssl3HttpAdapter(HTTPAdapter):
""""Transport adapter" that allows us to use SSLv3."""

def init_poolmanager(self, connections, maxsize, block=False):
    self.poolmanager = PoolManager(num_pools=connections,
                                   maxsize=maxsize,
                                   block=block,
                                   ssl_version=ssl.PROTOCOL_SSLv3)

有什么建议吗? 附注:我无法提供我的证书


你使用SSLv3的原因是什么?如果不是绝对必要,你应该转移到TLS,因为SSLv3已不再被认为是安全的。这也可能导致你的问题。请参阅http://disablessl3.com/了解有关为什么不应使用SSLv3的信息。 - Joey Wilhelm
这个 Web 服务至少在 PHP 中需要这样做,主要原因是我无法在没有定义 curl_setopt($oCurl, CURLOPT_SSLVERSION, 3) 的情况下使用它。我相信在 Python 中也需要这样做……如果没有这个适配器,我会遇到同样的错误。 - Matheus Hernandes
1个回答

1

[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:600)

证书无法被 Python 验证,并且无法被其他人验证,正如您可以在 this report from SSLLabs 中看到的。

PHP 可以正常工作,..

要么 PHP 明确信任证书或其颁发者,要么您正在使用旧版本的 PHP,默认情况下不验证证书,因此验证不会失败。

ssl_version=ssl.PROTOCOL_SSLv3)

根据SSLLabs的报告,此服务器实际上支持TLS 1.0(但不支持TLS 1.1或TLS 1.2),因此无需限制版本为SSL 3.0。


我明白了,但我的.pem文件可能有问题吗?如果Python无法验证它,我该如何设置我的证书以进行请求? - Matheus Hernandes
1
@MatheusHernandes:验证错误与您指定的(客户端)证书无关,而与服务器证书的验证有关。请参见http://docs.python-requests.org/en/latest/user/advanced/#ssl-cert-verification以了解如何将CA或证书添加为受信任的证书。 - Steffen Ullrich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接