asp.net-core - 从 C 核心客户端到 .NET 核心服务器的 HTTPS GRPC 连接:TLS 握手失败
问题描述
这个问题与我昨天问的一个问题密切相关,但我的诊断信息有很大的不同,以至于我认为我会更新并重新提交:让我知道是否应该删除其中一个。
我有一个用 .NET 核心编写的玩具 GRPC 服务器,我需要使用使用 grpc C 核心的客户端连接到该服务器。
您可以在此处找到.net 核心服务器的Startup.cs
and 。没有什么太有趣的了,除了调用. 我已经通过从.net 核心客户端(通过 https)连接到服务器来验证服务器是否正常工作。Program.cs
UseHttps
但是,我现在尝试从用 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++ 客户端将服务器的公钥加载到 an中,然后SslOpts.pem_root_certs
使用它来创建对象。Python 客户端根本不读取证书文件,并将其通道创建为. 不过我认为这并不重要:TLS 握手在交换任何证书信息之前失败。SslCredentials
Channel
grpc.secure_channel("localhost:50052", grpc.ssl_channel_credentials())
我使用wireshark查看数据包中是否有任何信息。从那里我可以看到 .NET 核心客户端发送此 TLS 客户端 hello,这会引发相应的服务器 hello。Python客户端发送的客户端hello是这样的(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
查找转换)启动客户端,但我只是因以下错误而大喊大叫
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)
解决方案
我的连接问题似乎是由我的机器上的一些错误配置引起的,因为我无法在其他设置上重现错误。这样就解决了“我如何让它工作?”
针对这三个具体问题,我回答了。
对我的grpc 问题有帮助的人得出的结论是,不,我提到的 TLS 版本的混合不是问题
我仍然不确定是什么导致一个客户端 hello 数据包被拒绝而另一个被接受,但这似乎是我的机器特有的东西,这在我创建的新 Windows Server 2019 或 Windows 10 VM 上不是问题
不确定这个:我很确定我正确设置了该环境变量,但我不确定为什么 openssl 无法识别该值。另外,我认为
GRPC_SSL_CIPHER_SUITES
对windows没有任何影响
推荐阅读
- jquery - Jquery 选择器不适用于使用 ajax 加载的元素
- visual-studio-code - 如何在 Visual Studio Code 中使滚动条更宽?
- python - python中的二进制文件操作
- azure-devops - VSTS 升级是否应用于继承的进程?
- mongodb - MongoDB 聚合管道 - 哪一步删除了最后一个文档?
- python - 打印格式 unicode 列表
- javascript - 使用滑块控制幻灯片放映速度
- sql - SQL 将 Null 日期或 1-1-1900 00:00:00 更改为当前日期
- c# - 问题创建管理员用户
- java - 如何等待基于 API 调用出现和消失的页面加载器在对元素执行操作之前消失