【发布时间】:2021-06-03 07:56:37
【问题描述】:
这个问题与one I asked yesterday 密切相关,但我的诊断信息有很大的不同,以至于我认为我应该更新并重新提交:如果我应该删除其中一个,请告诉我。
我有一个用 .NET 核心编写的玩具 GRPC 服务器,我需要使用使用 grpc C 核心的客户端连接到该服务器。
您可以找到 .net 核心服务器 here 的 Startup.cs 和 Program.cs。除了打电话给UseHttps 之外,没有什么太有趣的了。我已经通过从a .net core client 连接到服务器(通过 https)验证了服务器是否正常工作。
但是我现在尝试从用 C++ 和 python 编写的客户端连接到此服务器,结果是 GRPC 错误 14 和客户端的以下消息
E0304 08:36:58.510065400 4905 ssl_transport_security.cc:1455] Handshake failed with fatal error SSL_ERROR_SSL: error:10000410:SSL routines:OPENSSL_internal:SSLV3_ALERT_HANDSHAKE_FAILURE.
以及服务器端的以下消息。
dbug: Microsoft.AspNetCore.Server.Kestrel.Core.KestrelServer[2]
Connection id "0HM6UG4PBICBP" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel[1]
Connection id "0HM6UG4PBICBP" started.
dbug: Microsoft.AspNetCore.Server.Kestrel.Https.Internal.HttpsConnectionMiddleware[1]
Failed to authenticate HTTPS connection.
System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception.
---> System.ComponentModel.Win32Exception (0x80090367): No common application protocol exists between the client and the server. Application protocol negotiation failed.
C++ 客户端将服务器的公钥加载到SslOpts.pem_root_certs 中,并使用它来创建SslCredentials 和Channel 对象。 Python 客户端根本不读取证书文件,并将其通道创建为grpc.secure_channel("localhost:50052", grpc.ssl_channel_credentials())。不过我认为这并不重要:TLS 握手在交换任何证书信息之前失败。
我使用wireshark查看数据包中是否有任何信息。从那里我可以看到 .NET 核心客户端发送this TLS client hello,这会引发相应的server hello。 Python客户端发送的客户端hello看起来像this(C++包类似),服务器立即响应握手失败消息。
我对 TLS 的了解还很初步,但 .NET 和 Python hellos 之间的一些差异让我印象深刻。
- 工作中的 TLS hello 数据包似乎是 TLS 1.2“一直以来”。 TLS 序列的开头如下所示
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.2 (0x0303)
Length: 160
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 156
Version: TLS 1.2 (0x0303)
而失败的 TLS 数据包中对应的序列是
Transport Layer Security
TLSv1.2 Record Layer: Handshake Protocol: Client Hello
Content Type: Handshake (22)
Version: TLS 1.0 (0x0301)
Length: 512
Handshake Protocol: Client Hello
Handshake Type: Client Hello (1)
Length: 508
Version: TLS 1.2 (0x0303)
由于某种原因,中间提到了TLS 1.0
- 在服务器 hello 中,服务器选择
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)密码套件,在失败的 TLS hello 数据包中未提及。
当然还有其他区别,但在我未经训练的人看来,它们似乎不太相关。
除了“我如何让它发挥作用?”之外,我还有几个具体问题
-
当我看到 grpc 客户端通过 tls 1.2(引用 tls 1.0)发送它的 hello 时,为什么会抱怨与 ssl 3 相关的内容?
-
两个客户端 hello 数据包之间的真正区别是什么?我可以看到密码套件的差异,我之前提到的 TLS 版本,每个都有一些其他没有的扩展:但我不知道这里有什么相关的,特别是因为它与为什么 asp.net 核心有关服务器会拒绝客户端你好
-
我应该设置一些 grpc C-core 环境变量来解决这个问题吗?如果有,如何解决?我尝试使用
GRPC_SSL_CIPHER_SUITES=ECDHE-RSA-AES256-SHA384 python client.py启动客户端(查看了转换here),但我只是因为以下错误而大喊大叫
E0304 08:13:28.257362600 4893 ssl_transport_security.cc:815] Invalid cipher list: ECDHE-RSA-AES256-SHA384.
发送失败数据包的 python 客户端通过 Python 3、Ubuntu 18.04(在 WSL 上)运行
$ openssl version
OpenSSL 1.1.0g 2 Nov 2017 (Library: OpenSSL 1.1.1 11 Sep 2018)
【问题讨论】:
标签: asp.net-core ssl openssl grpc tls1.2