【问题标题】:HTTPS GRPC connections from C core clients to .NET core server: TLS handshake failure从 C 核心客户端到 .NET 核心服务器的 HTTPS GRPC 连接:TLS 握手失败
【发布时间】:2021-06-03 07:56:37
【问题描述】:

这个问题与one I asked yesterday 密切相关,但我的诊断信息有很大的不同,以至于我认为我应该更新并重新提交:如果我应该删除其中一个,请告诉我。

我有一个用 .NET 核心编写的玩具 GRPC 服务器,我需要使用使用 grpc C 核心的客户端连接到该服务器。

您可以找到 .net 核心服务器 hereStartup.csProgram.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 中,并使用它来创建SslCredentialsChannel 对象。 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 之间的一些差异让我印象深刻。

  1. 工作中的 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

  1. 在服务器 hello 中,服务器选择 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028) 密码套件,在失败的 TLS hello 数据包中未提及。

当然还有其他区别,但在我未经训练的人看来,它们似乎不太相关。

除了“我如何让它发挥作用?”之外,我还有几个具体问题

  1. 当我看到 grpc 客户端通过 tls 1.2(引用 tls 1.0)发送它的 hello 时,为什么会抱怨与 ssl 3 相关的内容?

  2. 两个客户端 hello 数据包之间的真正区别是什么?我可以看到密码套件的差异,我之前提到的 TLS 版本,每个都有一些其他没有的扩展:但我不知道这里有什么相关的,特别是因为它与为什么 asp.net 核心有关服务器会拒绝客户端你好

  3. 我应该设置一些 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


    【解决方案1】:

    我的连接问题似乎是由我的机器上的一些错误配置引起的,因为我无法在其他设置上重现错误。这样就解决了“我如何让它工作?”

    针对我回答的这三个具体问题。

    1. grpc issue 上的乐于助人的人得出的结论是,不,我提到的 TLS 版本的混合不是问题

    2. 我仍然不确定是什么导致一个客户端 hello 数据包被拒绝而另一个被接受,但这似乎是我的机器特有的东西,这在新的 Windows Server 2019 或 Windows 10 VM 上不是问题我已创建

    3. 不确定这个:我很确定我正确设置了该环境变量,但我不确定为什么 openssl 无法识别该值。另外,我不认为GRPC_SSL_CIPHER_SUITES对windows有任何影响

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-08
      • 1970-01-01
      • 2012-12-22
      • 2019-07-20
      • 1970-01-01
      • 1970-01-01
      • 2012-04-16
      • 2021-09-21
      相关资源
      最近更新 更多