【问题标题】:Unable to connect sockets with SSL certifcate signed by CA无法使用 CA 签署的 SSL 证书连接套接字
【发布时间】:2020-09-09 00:55:12
【问题描述】:

我有一个在 Ubuntu 18.04 上运行的 Socket 服务器,我正在尝试使用 SSL/TLS 运行它。首先,我使用了自签名证书,代码运行良好,但现在我尝试使用由 ZeroSSL 签名的 90 天免费 SSL 证书,但它不起作用。以下是我在请求连接时在服务器和客户端收到的错误消息。

服务器端错误: ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:852)

客户端错误: ssl.SSLCertVerificationError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1076)

服务器代码:

import ssl
import socket

IP = "0.0.0.0"
PORT = 2021
server_cert = "/home/ubuntu/chandral/ssl_socket_test/Certificates/Ubuntu/certificate.crt"
#server_cert = "/home/ubuntu/chandral/ssl_socket_test/Certificates/Ubuntu/ca_bundle.crt"
server_key = "/home/ubuntu/chandral/SSL/server.key"
context = ssl.create_default_context(purpose=ssl.Purpose.CLIENT_AUTH)
context.load_cert_chain(certfile=server_cert, keyfile=server_key)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
secure_server_socket = context.wrap_socket(server_socket, server_side=True)
secure_server_socket.bind((IP, PORT))
secure_server_socket.listen(5)
print("listening for connections")
while True:
    client_socket, address = secure_server_socket.accept()
    print("IP/URL of client:", address)

客户代码:

import ssl
import socket

IP = "192.168.1.1" # IP changed in this post for confidentiality
PORT = 2021
server_sni_hostname = "example.com" # Domain changed in this post for confidentiality
context = ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
secure_client_socket = context.wrap_socket(client_socket, server_side=False, server_hostname=server_sni_hostname)
secure_client_socket.connect((IP, PORT))
secure_client_socket.send(b"Hello World")

【问题讨论】:

  • 您的certificate.crt 的内容未知,但对问题很重要。我的猜测是您只是缺少必要的中间证书(ca_bundle.crt)并且只提供叶证书。您需要将 certificate.crtca_bundle.crt 组合在一起并使用结果而不仅仅是叶证书。
  • 非常感谢,它现在可以工作了,必须在合并文件的两个证书之间手动输入一个新行。请将此作为答案发布,以便我可以投票并接受它。

标签: python sockets ssl openssl ssl-certificate


【解决方案1】:
server_cert = "/home/ubuntu/chandral/ssl_socket_test/Certificates/Ubuntu/certificate.crt"
#server_cert = "/home/ubuntu/chandral/ssl_socket_test/Certificates/Ubuntu/ca_bundle.crt"

ZeroSSL provides three filescertificate.crt 是服务器的叶证书,private.key 是私钥(您的代码中为 server.key),ca_bundle.crt 是中间证书和根证书。

服务器必须同时提供叶证书和所有链证书,以便客户端can build the trust chain 获得本地根 CA 证书。要创建这样的设置,您需要将certificate.crt 的内容与ca_bundle.crt 连接起来,并将结果与​​context.load_cert_chain(...) 一起使用。请注意,可能需要在 certificate.crt 之后添加一个明确的换行符,以防文件末尾缺少它。另请注意,不需要包含自签名根 CA(ca_bundle.crt 中的最后一个证书),因为无论如何客户端都会忽略它,而是使用本地根 CA。实际上建议将其省略。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-10
    • 2021-01-29
    • 2014-01-06
    • 2013-02-28
    • 1970-01-01
    • 2017-05-08
    • 2016-11-24
    • 1970-01-01
    相关资源
    最近更新 更多