验证证书失败后从socket对象获取ssl客户端证书

问题描述 投票:0回答:1

我有一个用 python 编写的套接字服务器,接受如下连接:

self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# set the socket as non-blocking
self.socket.setblocking(False)

# bind
self.socket.bind((self.host, int(self.port)))

# listen
self.socket.listen()

在一个单独的异步函数中,我调用:

conn, address = await self.loop.sock_accept(self.socket)

一旦建立连接,它就会被传递到:

loop.connect_accepted_socket(lambda: <custom asyncio.Protocol class>, ssl=ssl_context)

当连接建立失败时,错误捕获如下:

except ssl.SSLError as e:
   print(e)

其中

e
可以是一系列 ssl 错误。

其中一些是:

  1. [SSL:WRONG_VERSION_NUMBER]
  2. [SSL: SSLV3_ALERT_BAD_CERTIFICATE] sslv3 警报错误证书 (_ssl.c:1091)

在这种情况下,我希望能够打印出我们从客户那里收到的证书。

有办法做到这一点吗?

我尝试在异常处理程序中打印

conn.getpeercert()
,但是我收到错误消息:

AttributeError:“socket”对象没有属性“getpeercert”

然而,如果连接成功,我可以通过调用从传输对象获取对等证书:

transport.get_extra_info("peercert")

我想知道是否有办法在验证失败时打印从客户端收到的证书。

python python-3.x sockets networking python-asyncio
1个回答
1
投票

如果是 WRONG_VERSION_NUMBER,服务器将不会发送证书。使用 SSLV3_ALERT_BAD_CERTIFICATE,由于套接字关闭,证书已经消失,因此您需要在套接字关闭之前捕获它。

在查看底层 OpenSSL 时,在这种情况下捕获证书的常用方法是在 SSL 上下文上实现 SSL 验证回调。但这个功能并没有在 Python 中公开,所以你可能不走运。

© www.soinside.com 2019 - 2024. All rights reserved.