python中SSL客户端的正确证书用途是什么?
我正在python应用程序中设置SSL客户端验证。目前,我的概念验证代码只是在建立一个安全连接 看起来我生成的证书要么没有必要的权限(更可能是IMO),要么有服务器无法理解或接受的权限(不太可能是IMO) 这应该是相对琐碎的,但我找不到正确的文档 我已经通过OpenSSL生成了服务器和客户端证书。我以前在其他应用程序中也这样做过,没有任何问题。但我对创建客户端证书不太熟悉。OpenSSL报告我使用的客户端证书具有扩展:python中SSL客户端的正确证书用途是什么?,python,ssl,client-certificates,Python,Ssl,Client Certificates,我正在python应用程序中设置SSL客户端验证。目前,我的概念验证代码只是在建立一个安全连接 看起来我生成的证书要么没有必要的权限(更可能是IMO),要么有服务器无法理解或接受的权限(不太可能是IMO) 这应该是相对琐碎的,但我找不到正确的文档 我已经通过OpenSSL生成了服务器和客户端证书。我以前在其他应用程序中也这样做过,没有任何问题。但我对创建客户端证书不太熟悉。OpenSSL报告我使用的客户端证书具有扩展: X509v3 extensions: X509v3 Subject
X509v3 extensions:
X509v3 Subject Key Identifier:
AF:AB:9D:AA:88:96:F4:0C:F5:56:9A:2C:DB:B6:BA:D9:DD:11:69:45
X509v3 Subject Alternative Name:
email:a@example.com
X509v3 Basic Constraints:
CA:FALSE
Netscape Cert Type:
SSL Client
X509v3 Authority Key Identifier:
keyid:E1:35:7C:39:7F:39:A4:43:D2:F8:00:59:38:91:71:AF:B9:38:AD:3F
X509v3 Key Usage:
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Client Authentication
简单的服务器测试代码是:
导入ssl
导入套接字
导入日志记录
_log=logging.getLogger(_名称__)
def main():
context=ssl.create\u default\u context(ssl.Purpose.CLIENT\u AUTH)
上下文。加载证书链(“1B.pem”、“key2.pem”)
context.verify\u mode=ssl.CERT\u必需
context.load\u verify\u位置(“my\u ca.crt”)
原始服务器套接字=socket.socket(socket.AF\u INET,socket.SOCK\u流,0)
尝试:
#为SO问题替换域
原始服务器socket.bind(('neptune.example.com',8812))
原始服务器套接字。侦听(5)
server\u socket=context.wrap\u socket(原始服务器\u socket,服务器端=True)
除例外情况外:
原始服务器套接字。关闭()
提升
使用服务器\u套接字:
尽管如此:
尝试:
连接到客户端,地址=server\u socket.accept()
连接到客户端时:
连接到客户端。写入(b'Hello')
例外情况除外,例如:
印刷品(ex)
如果名称=“\uuuuu main\uuuuuuuu”:
main()
这会产生以下错误:
[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unsupported certificate purpose (_ssl.c:1076)
。。。当客户端与此连接时:
导入套接字
导入ssl
context=ssl.create\u default\u context(ssl.Purpose.SERVER\u AUTH)
加载证书链(“1C.pem”、“key.pem”)
原始套接字=socket.socket(socket.AF\u INET,socket.SOCK\u流)
#域已更改,因此出现问题
conn=context.wrap\u套接字(原始套接字,服务器端=False,服务器主机名=“neptune.example.com”)
conn.connect((“neptune.example.com”,8812))
康涅狄格州关闭
正如Steffen Ullrich所暗示的,问题似乎不是证书本身,而是我用来签署证书的CA证书
CA证书的授权权限有限。它们与它们签署的证书在相同的扩展中表示。因此,CA要将证书作为客户端SSL证书进行签名,客户端证书和CA证书必须具有:
- “数字签名”的密钥用法
扩展名AKA1.3.6.1.5.5.7.3.2
TLS Web客户端身份验证
X509v3 Key Usage:
Digital Signature
X509v3 Extended Key Usage:
TLS Web Client Authentication
在我的例子中,CA没有扩展使用
1.3.6.1.5.5.7.3.2
。服务器证书可以,但无法签署客户端证书。具有完全相同的密钥用法、扩展密钥用法、netscape证书类型和基本约束的客户端证书对我来说可以正常工作。请注意,此错误也可能来自链中的证书,因此最好提供所涉及的所有证书或它们产生的确切方式,以便重现您的问题。或者您可以尝试我使用的测试证书(client-*.pem、server-*.pem、test-ca.pem)