我开发了一个使用 SSL (TLSv1-TLSv1.2) 并禁用密码和不安全协议(protocol)的 CherryPy REST 服务。
现在我有另一段代码使用 Python 请求连接到此服务。我已经编写了一个 TLS HTTPAdapter 并且请求成功。我只有一个问题:
我既没有看到在服务器端也没有在客户端选择了什么密码。所以事实上,我真的不知道我的安全选项是否发生了。我找不到如何从为 CherryPy 或请求调用的内置 Python 模块中获取 SSLSocket.cipher()。
是否有一种简单的方法来获取这些信息?
这是一个例子:
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.poolmanager import PoolManager
class Tlsv1_2HttpAdapter(HTTPAdapter):
""""Transport adapter" that allows us to use TLSv1.2"""
def init_poolmanager(self, connections, maxsize, block=False):
self.poolmanager = PoolManager(
num_pools=connections, maxsize=maxsize,
block=block, ssl_version=ssl.PROTOCOL_TLSv1_2)
con = "https://{}:{}".format(host, port)
tls = Tlsv1_2HttpAdapter()
try:
s = requests.Session()
s.mount(con, tls)
r = s.get(con)
except requests.exceptions.SSLError as e:
print(e, file=sys.stderr)
sys.exit(1)
我想要这样的东西:print("Cipher used: {}".format(foo.cipher()))
非常感谢您的帮助
最佳答案
作为测试的临时解决方案,下面的代码打印出密码套件(位置 0)和协议(protocol)(位置 1):
('ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256)
Python 2.7(已测试):
from httplib import HTTPConnection
def request(self, method, url, body=None, headers={}):
self._send_request(method, url, body, headers)
print(self.sock.cipher())
HTTPConnection.request = request
Python 3(tested on v3.8.9 by comment below):
from http.client import HTTPConnection
def request(self, method, url, body=None, headers={}, *,
encode_chunked=False):
self._send_request(method, url, body, headers, encode_chunked)
print(self.sock.cipher())
HTTPConnection.request = request
这是猴子修补 request()
方法的唯一原因是添加打印语句。如果你想更好地控制输出,你可以用调试记录器替换打印功能。
将此代码段导入或粘贴到代码的开头,以便它可以尽快修补该方法。
关于Python 请求为 HTTPS 打印使用的密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36102451/