【问题标题】:How can I connect a gRPC client in .NET framework with a secure .NET Core server?如何将 .NET 框架中的 gRPC 客户端与安全的 .NET Core 服务器连接起来?
【发布时间】:2023-03-26 07:44:02
【问题描述】:

我在 .NET Core 服务器上使用 protobuf-net.Grpc 并尝试从 .NET Framework (4.7.2.) gRPC 客户端进行调用。一个完整的例子在这里:https://github.com/angelagyang/GRPCProtobufExample

这是我客户的 sn-p:

var channelCreds = new SslCredentials(GetRootCertificates());
var channel = new Channel("localhost", 5001, channelCreds);
var greeter = channel.CreateGrpcService<IGreeterService>();

使用此配置,我在调用服务器时收到错误StatusCode="Unknown", Detail="Stream removed"...。如果我在服务器上设置ClientCertificateMode = ClientCertificateMode.NoCertificate,我就可以连接到服务器。 但是,我希望服务器到require a client certificate and validate the certificate via thumbprint

例如,在 .NET Core 中,我可以使用 Grpc.Net.Client 来配置我的频道,如下所示:

var handler = new HttpClientHandler();
handler.ClientCertificates.Add(certificate);
var channel2 = GrpcChannel.ForAddress("https://localhost:5001", new GrpcChannelOptions
{
      HttpHandler = handler
});

有没有办法像这样在 .NET Framework 中配置带有证书的客户端?我对 gRPC/.NET 还是很陌生,如果有任何建议,我将不胜感激!

【问题讨论】:

  • 我找到了一个与您的示例相似但有一些差异的示例,也许它可以提供帮助:grpc.io/docs/guides/auth(查找文本 C#
  • 非常有趣的问题。明天我会试着做一些挖掘工作。
  • GRPC 是 HTTP/2。 Peter 的链接只是在连接开始时使用 TCP 完成的 SSL/TLS 安全性,并不是整个解决方案。 OP 发布顶部的链接不会一直有效。当客户端和服务器在同一台机器上时,它将不起作用,因为它们都使用 localhost。如果机器将环回 IP 127.0.0.1 作为本地主机,该代码也将不起作用。建立 TCP 连接的建议是服务器始终使用 IPAddress.Any 作为端点。客户端应该连接到服务器的 IP 或使用 DNS.GetHost 然后使用地址数组的索引 1。

标签: c# .net .net-core grpc protobuf-net


【解决方案1】:

解决并更新了原来的例子:https://github.com/angelagyang/GRPCProtobufExample

您可以通过创建KeyCertificatePair 来配置客户端证书以传递到SslCredentials。您将需要 PEM 编码的证书链和 PEM 编码的私钥。

var keyCertPair = new KeyCertificatePair(File.ReadAllText($"{rootDir}/cert.pem"), File.ReadAllText($"{rootDir}/cert.key")); 
var channelCreds = new SslCredentials(GetRootCertificates(), keyCertPair);

出于测试目的,我在这里使用了自签名证书:https://github.com/grpc/grpc/tree/master/src/core/tsi/test_creds

调试时,设置GRPC_VERBOSITY = DEBUGGRPC_DEBUG = ALL。这可以帮助清除模糊的错误消息。例如,我意识到我用来配置 HTTPS 的服务器证书不包括 localhost。

【讨论】:

  • 我的 gRPC 服务上有一个带有私钥的证书,但是我需要在我的客户端上使用 pfx,为什么不用 .cer 没有将私钥转换为 PEM?我必须使用 keyCertPair 吗?如何在 Visual Studio 和 C# 中设置这些变量?
【解决方案2】:

根据我的尝试和工作,您可以跳过阅读cert.pemcert.key 的工作。此外,GetRootCertificate() 仅在服务器系统托管在众所周知的受信任网站(如 google.commsdn.com 或类似它和 localhost 的情况下)才能工作。更详细的答案可以找到herehere

如果我们打算将我们自己的主机 DNS 与 SSL 一起使用,那么在分配给您的 DNS 的 pfx 中生成服务器证书并将其转换为客户端应用程序的 pem 是您的方法。 使用 openssl 等工具将有助于转换证书编码。

openssl pkcs12 -in "<DiskLocationOfPfx>\ProjectName.pfx" -out "<TargetLocation>\certifcate.pem" -clcerts

将服务器证书转换为 pem 后,您可以使用

var channelCreds = new SslCredentials(File.ReadAllText($"{rootDir}/cert.pem"));
var channel = new Channel("www.youdns.com", 5001, secureCredentials);

【讨论】:

  • 我的 gRPC 服务上有一个带有私钥的证书,但是我需要在我的客户端上使用 pfx,为什么不用 .cer 没有将私钥转换为 PEM?
  • 在客户端使用 pem。或安装证书是证书根存储。并从商店读取
  • 已经试过了。你可以看看我的例子:github.com/hovek/grpc_certifier_example
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-11
  • 2020-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多