在服务器上,我用我的私钥初始化 SSLContext,我从 caroot.crt 文件加载的 CA 提供的证书文件。现在,当我用 node 之类的东西初始化它时,一切正常(例如: Setting up SSL with node.js )。我的意图是以相同的方式设置所有内容。我的假设是,在握手期间,服务器正在为客户端提供 CA,就像我的节点服务器一样。好像不是这样的。我做错了什么?
如果未使用 ssl.CERT_REQUIRED,则一切正常,但我想验证端点(服务器)是否如他们所说。
# Server
import socket
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
context.load_cert_chain(certfile='./path/to/certfile.crt',
keyfile='./path/to/keyfile.pem')
context.load_verify_locations('./path/to/caroot.crt')
context.set_default_verify_paths()
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('', 23000))
server_socket.listen(socket.SOMAXCONN)
def handle_client(ssl_socket):
data = ssl_socket.read()
while data:
print("%s" % (str(data)))
data = ssl_socket.read()
while True:
client_socket, addr = server_socket.accept()
ssl_client_socket = context.wrap_socket(client_socket, server_side=True)
handle_client(ssl_client_socket)
# Client
import socket
import ssl
context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
# I'm assuming this is not necessary, but I'd like to load the system provided CAs
context.set_default_verify_paths()
# Require CA validation to prevent MITM.
context.verify_mode = ssl.CERT_REQUIRED
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssl_client = context.wrap_socket(client_socket)
ssl_client.connect(('', 23000))
ssl_client.send(bytes('hello, world!', 'UTF-8'))
最佳答案
事实证明,我的 CA 提供了 3 个不同的 crt 文件。我的解决方案是以特定顺序附加它们以生成传递给 context.load_verify_locations
的正确 CA 链。
对于任何使用 COMODO 作为提供商的人,这里有一篇博文:http://billpatrianakos.me/blog/2014/04/04/installing-comodo-positive-ssl-certs-on-apache-and-openssl/
当然,该帖子是特定于 Apache 的,前提仍然是相同的。有问题的命令是:
cat COMODORSADomainValidationSecureServerCA.crt COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt > yourdomain.com.cer
然后你做:
context.load_verify_locations('yourdomain.com.cer')
现在一切都按预期工作。
关于python - 颁发的 CA 导致 TLSV1_ALERT_UNKNOWN_CA。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26308001/