无法在Tornado中使用SSL客户端证书

车床

我需要在Tornado中设置客户端-服务器认证的通信。我生成了根CA证书,然后将其用于签署服务器和客户端证书。当我使用openssl验证这些证书时,一切看起来都很好(请参见下文)。但是,当我在Tornado中使用相同的密钥和证书时,会收到“ tlsv1警报未知ca”。

龙卷风服务器:

context = ssl.SSLContext(ssl.PROTOCOL_TLSv1_2)                                                                                                                            
context.verify_mode = ssl.CERT_REQUIRED
context.load_cert_chain("/home/soustruh/cert/server.cert.pem",
        "/home/soustruh/cert/server.key.pem")
context.load_verify_locations("/home/soustruh/cert/rootCA.pem")

server = tornado.httpserver.HTTPServer(application, ssl_options=context)
server.listen(6090)
tornado.ioloop.IOLoop.instance().start()

龙卷风客户:

url = "https://127.0.0.1:6090/" 
request = tornado.httpclient.HTTPRequest(url = url, method = "GET", 
        client_key="/home/soustruh/cert/client.key.pem",
        client_cert="/home/soustruh/cert/client.cert.pem")
client = tornado.httpclient.AsyncHTTPClient()
param = yield client.fetch(request, self.handle_request)

客户端错误:

WARNING:tornado.general:SSL Error on 10 ('127.0.0.1', 6090): [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)
Error: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:598)

服务器错误:

WARNING:tornado.general:SSL Error on 9 ('127.0.0.1', 47104): [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:598)
ERROR:tornado.general:Uncaught exception
Traceback (most recent call last):
  File "/usr/local/lib/python3.4/dist-packages/tornado/http1connection.py", line 674, in _server_request_loop
    ret = yield conn.read_response(request_delegate)
  File "/usr/local/lib/python3.4/dist-packages/tornado/gen.py", line 617, in run
    value = future.result()
  File "/usr/local/lib/python3.4/dist-packages/tornado/concurrent.py", line 109, in result
    raise_exc_info(self._exc_info)
  File "<string>", line 3, in raise_exc_info
  File "/usr/local/lib/python3.4/dist-packages/tornado/gen.py", line 620, in run
    yielded = self.gen.throw(*sys.exc_info())
  File "/usr/local/lib/python3.4/dist-packages/tornado/http1connection.py", line 165, in _read_message
    io_loop=self.stream.io_loop)
  File "/usr/local/lib/python3.4/dist-packages/tornado/gen.py", line 617, in run
    value = future.result()
  File "/usr/local/lib/python3.4/dist-packages/tornado/concurrent.py", line 111, in result
    raise self._exception
  File "/usr/local/lib/python3.4/dist-packages/tornado/iostream.py", line 1167, in _do_ssl_handshake
    self.socket.do_handshake()
  File "/usr/lib/python3.4/ssl.py", line 805, in do_handshake
    self._sslobj.do_handshake()
ssl.SSLError: [SSL: TLSV1_ALERT_UNKNOWN_CA] tlsv1 alert unknown ca (_ssl.c:598)

仅作记录,openssl验证:

openssl verify -CAfile /home/soustruh/cert/rootCA.pem /home/soustruh/cert/server.cert.pem 
/home/soustruh/cert/server.cert.pem: OK
openssl verify -CAfile /home/soustruh/cert/rootCA.pem /home/soustruh/cert/client.cert.pem 
/home/soustruh/cert/client.cert.pem: OK

当我使用openssl创建服务器和客户端时,它也可以工作。

OpenSSL服务器

openssl s_server -accept 12345 -cert server.cert.pem -key server.key.pem -CAfile rootCA.pem 
Using default temp DH parameters
Using default temp ECDH parameters
ACCEPT
-----BEGIN SSL SESSION PARAMETERS-----
MFUCAQECAgMDBALAMAQABDBq9HZ1LyiuB7i+UKpwYBVwMB3H2WN6AYZjKulQcDgk
x44vTFGwRL2hcj/3b/eXU76hBgIEU/xOWaIEAgIBLKQGBAQBAAAA
-----END SSL SESSION PARAMETERS-----
Shared ciphers:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:SRP-DSS-AES-256-CBC-SHA:SRP-RSA-AES-256-CBC-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-DSS-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:SRP-DSS-3DES-EDE-CBC-SHA:SRP-RSA-3DES-EDE-CBC-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-DES-CBC3-SHA:DES-CBC3-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:SRP-DSS-AES-128-CBC-SHA:SRP-RSA-AES-128-CBC-SHA:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:DHE-RSA-SEED-SHA:DHE-DSS-SEED-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:ECDH-RSA-AES128-GCM-SHA256:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA:ECDH-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:SEED-SHA:CAMELLIA128-SHA:ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:ECDH-RSA-RC4-SHA:ECDH-ECDSA-RC4-SHA:RC4-SHA:RC4-MD5:EDH-RSA-DES-CBC-SHA:EDH-DSS-DES-CBC-SHA:DES-CBC-SHA:EXP-EDH-RSA-DES-CBC-SHA:EXP-EDH-DSS-DES-CBC-SHA:EXP-DES-CBC-SHA:EXP-RC2-CBC-MD5:EXP-RC4-MD5
CIPHER is ECDHE-RSA-AES256-GCM-SHA384
Secure Renegotiation IS supported

OpenSSL客户端:

openssl s_client -connect 127.0.0.1:12345 -verify 2 -cert client.cert.pem -key client.key.pem 
verify depth is 2
CONNECTED(00000003)
~
verify error:num=19:self signed certificate in certificate chain
verify return:1
~
verify return:1
~
verify return:1
---
Certificate chain
~~~
---
Server certificate
-----BEGIN CERTIFICATE-----
~~~
-----END CERTIFICATE-----
~~~
---
No client certificate CA names sent
---
SSL handshake has read 3122 bytes and written 443 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES256-GCM-SHA384
Server public key is 4096 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES256-GCM-SHA384
    Session-ID: 9CDDF8FC4976A85112087356F329AC32FAFCF07E198AA50565B3BE8FE8476E1C
    Session-ID-ctx: 
    Master-Key: 6AF476752F28AE07B8BE50AA70601570301DC7D9637A0186632AE950703824C78E2F4C51B044BDA1723FF76FF79753BE
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    TLS session ticket lifetime hint: 300 (seconds)
    TLS session ticket:
    0000 - a1 78 18 17 2d db 2f 32-81 31 71 50 09 c0 5a 3e   .x..-./2.1qP..Z>
    0010 - 7a de 73 a3 79 30 07 71-ab 3e 77 60 03 17 43 fe   z.s.y0.q.>w`..C.
    0020 - bd 8f 71 7a 3f 27 a0 3d-de 74 03 fe c8 3e fe b3   ..qz?'.=.t...>..
    0030 - 1e c0 c7 80 64 8f 88 e7-2c 1c a1 6a 32 f1 a9 e7   ....d...,..j2...
    0040 - 86 1e b0 a7 ad 55 3d 04-f6 9d 9f a7 75 44 3b d3   .....U=.....uD;.
    0050 - 90 1a fc 6b 41 2c 47 aa-b7 70 6c 33 35 ae 1c 54   ...kA,G..pl35..T
    0060 - b4 5b 95 9b a7 7b ed 03-73 e3 34 f1 61 6c 9a ac   .[...{..s.4.al..
    0070 - 17 c5 0d 65 23 0f da 74-0c ba cc c7 bf e1 c9 67   ...e#..t.......g
    0080 - 38 3f 70 78 e5 c5 c3 4e-2d 6b 33 47 30 76 20 00   8?px...N-k3G0v .
    0090 - 50 f6 fe dd 0a 88 c3 c0-fa 1f 26 62 f1 14 3f e8   P.........&b..?.

    Start Time: 1409044057
    Timeout   : 300 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
---
车床

好,回答我自己。关键问题是我没有在客户端中指定CA证书的路径(请参阅帮助我找到正确方法的答案)。正确的客户端代码是:

request = tornado.httpclient.HTTPRequest(url = url, method = "GET", 
        client_key="/home/soustruh/cert/client.key.pem",
        client_cert="/home/soustruh/cert/client.cert.pem",
        ca_certs="/home/soustruh/cert/rootCA.pem")
client = tornado.httpclient.AsyncHTTPClient()
param = yield client.fetch(request, self.handle_request)

我的问题是我认为验证返回码:19(证书链中的自签名证书)是某种“警告成功”的答案。实际上,当您还在openssl s_client中指定CA文件时:

openssl s_client -connect 127.0.0.1:12345 -verify 2 -cert client.cert.pem -key client.key.pem -state -CAfile rootCA.pem

您得到验证返回码:0(确定)

我还生成了一个由根CA签名的中间CA,但这不是必需的。:-)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在Curl命令中使用客户端证书

使用Jersey客户端忽略自签名的SSL证书

如何在Apache HttpClient中使用SSL客户端证书?

如何在Spring-Boot中使用SSL证书并为Android客户端生成公钥

在Java中使用同一主机使用多个SSL客户端证书

使用自签名证书的Java ssl / https客户端

如何在客户端Java应用程序中使用客户端证书?

如何在HTTPS中使用客户端证书?

在Alamofire 2.0中使用客户端证书

码头:如何在码头客户端中使用SSL

SSL客户端证书Microsoft Edge

aiohttp和客户端SSL证书

在WebJob中使用客户端证书

客户端证书:无法使用权限建立SSL / TLS的安全通道(再次!)

如何在Scrapy中使用SSL客户端证书(p12)?

使用客户端证书的扭曲的HTTP客户端

无法使用OpenSSL的ssl.SSLContext()在Python客户端中接收对等证书

无法从Tornado客户端连接到基于Tornado SSL的服务器

如何在.Net Core中使用客户端SSL证书

使用Xamarin Android与客户端证书进行SSL通信

使用wsimport创建SOAP客户端,但无法使其与SSL证书一起使用

无法在Windows 10的Chrome或IE中使用客户端证书

客户端的SSL证书

IntelliJ Rest客户端:将客户端SSL证书与rest调用一起使用

Java证书客户端SSL:无法找到请求的目标的有效证书路径

禁用客户端SSL证书

无法在 ASP.NET Core 2.1 中使用具有客户端证书的 SOAP 服务

NGINX 使用客户端证书 (ssl_verify_client)

在 Jenkins 中使用 withCredentials 绑定中的客户端证书