首页 > 解决方案 > SSL 错误(从 Python 2.7.15 到 Python 3.7.7 的端口)- HTTP 错误 401:消息验证失败

问题描述

将代码从 Python 2.7.15 移植到 Python 3.7.7,我无法让我们的 SSL 调用连接到内部服务器。

在每个版本的 Python 中运行此代码,我得到:

import socket, ssl

context =  context = ssl.create_default_context()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
domain = 'xxx.yyy.com'
sslSocket = context.wrap_socket(s, server_hostname = domain)
sslSocket.connect((domain, 443))
print('the selected version by the server: ', sslSocket.cipher()[1])

Python 2.7.15 中的结果 -

('服务器选择的版本:', 'TLSv1/SSLv3')

Python 3.7.7 中的结果 -

服务器选择的版本:TLSv1.2

此外,我正在为我的 SSL 调用设置如下上下文:

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)

如何在 3.7.7 中设置我的上下文以满足服务器的要求?

谢谢你的帮助!问候,迈克尔

史蒂芬,谢谢你的帮助!我花时间调查并发布了调试日志。在 Python 3.7 中,第一次调用 urlIib2.open() 中的 self._open() 会返回一个包含 401 错误代码的错误处理程序对象。我不确定这是否有帮助-如果我需要提供其他信息,请告诉我...谢谢。我有更多关于结构内容等的信息,但不想不知所措。请让我知道我错过了什么......

我使用以下代码启用了日志记录:

import requests
import logging
from http.client import HTTPConnection  # py3
log = logging.getLogger('urllib3')
log.setLevel(logging.DEBUG)
# logging from urllib3 to console
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
log.addHandler(ch)
# print statements from `http.client.HTTPConnection` to console/stdout
HTTPConnection.debuglevel = 1
requests.get('http://httpbin.org/')

这是每个测试的日志记录信息:

Python 2.7.15
Starting new HTTP connection (1): httpbin.org:80
send: 'GET / HTTP/1.1\r\nHost: httpbin.org\r\nConnection: keep- 
alive\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nUser-Agent: python- requests/2.19.1\r\n\r\n'
http://httpbin.org:80 "GET / HTTP/1.1" 200 9593
reply: 'HTTP/1.1 200 OK\r\n'
header: Date: Thu, 20 Aug 2020 19:53:40 GMT
header: Content-Type: text/html; charset=utf-8
header: Content-Length: 9593
header: Connection: keep-alive
header: Server: gunicorn/19.9.0
header: Access-Control-Allow-Origin: *
header: Access-Control-Allow-Credentials: true


Python 3.7.7
Starting new HTTP connection (1): httpbin.org:80
send: b'GET / HTTP/1.1\r\nHost: httpbin.org\r\nUser-Agent: python- requests/2.22.0\r\nAccept-Encoding: gzip, deflate\r\nAccept: */*\r\nConnection:keep-alive\r\n\r\n'
http://httpbin.org:80 "GET / HTTP/1.1" 200 9593
reply: 'HTTP/1.1 200 OK\r\n'
header: Date: Thu, 20 Aug 2020 20:40:58 GMT
header: Content-Type: text/html; charset=utf-8
header: Content-Length: 9593
header: Connection: keep-alive
header: Server: gunicorn/19.9.0
header: Access-Control-Allow-Origin: *
header: Access-Control-Allow-Credentials: true
exception HTTP Error 401: Message validation failed

标签: pythonssl

解决方案


我认为您正在寻找错误的地方来解决问题的原因。

由于您已返回代码 401,这意味着已收到 HTTP 响应。这意味着在 HTTPS 的情况下,TLS 握手必须成功完成,否则可能不会收到任何应用程序数据(因此也不会收到 HTTP 响应)。因此,问题很可能不在于 TLS 握手,而在于稍后 - 在您未显示的代码中。


推荐阅读