【问题标题】:gRPC SSL communication for .NET Framework to .NET Core Server.NET Framework 到 .NET Core 服务器的 gRPC SSL 通信
【发布时间】:2020-11-12 00:20:34
【问题描述】:

我可以将 C# Full .NET Framework Client 与具有安全通道的 C# .NET core 客户端一起使用吗?

你能引导我举一些例子吗?如果可以做到或无法做到,我找不到任何地方。

详情: 我使用 .NET Framework 客户端和 Grpc C# Github 作为参考,使用 .NET Core 客户端和 Grpc dotnet 中的这个示例作为参考。 我能够与

建立不安全的沟通渠道

new Channel("127.0.0.1", 5000, ChannelCredentials.Insecure)

以及在 ASP.NET Core 服务器中打开的 5000 的 Non-Https 端口。

当我尝试连接时

var channel = new Channel("127.0.0.1", 5001, new SslCredentials());

到 ASP.NET Core Server 中的 Https 端口 5000I

如何使用安全通道进行通信。我想使用相同的 pfx + 密码组合。

【问题讨论】:

    标签: c# .net asp.net-core protocol-buffers grpc


    【解决方案1】:

    查看my question and answer here。我创建了一个可能有用的基本示例:https://github.com/angelagyang/GRPCProtobufExample

    您可以通过创建 KeyCertificatePair 来配置客户端证书以传递到 SslCredentials。您将需要三个 PEM 编码的字符串:

    1. PEM 编码的客户端证书链
    2. PEM 编码的私钥
    3. PEM 编码的服务器 SSL 证书。

    这是一个示例设置:

    var keyCertPair = new KeyCertificatePair(clientsslcert.pem, privatekey.pem); 
    var channelCreds = new SslCredentials(serversslcert.pem, keyCertPair);
    

    出于测试目的,我找到了these test PEMs helpful。我使用OpenSSL 将 PFX 转换为 PEM 格式。此外,this post 更多地讨论了不同的 PEM 字符串以及客户端需要明确信任服务器的原因。

    【讨论】:

    • 这是一个很好的解决方案,但我想尽可能减少代码。我在没有 keyCertPair 部分的情况下完成了这项工作,但将 pem 作为文本读取。请查看我的解决方案。
    • 很高兴听到这个消息! KeyCertificatePair 仅在您想要实现客户端证书验证时才需要使用(即,如果服务器想要验证客户端的证书以增加一层安全性)。
    • 我找到了一种不需要在客户端存储 pem 的方法,也许它对其他人也有用:stackoverflow.com/a/66041094/727250
    【解决方案2】:

    我发布此答案是为了让下一个人寻找解决方案。 在我得到它之后,我在类似的用例问题中发布了我的解决方案 herehere

    -- 以下是我自己的回答。

    无论是否通过 SSL,您都需要在 ASP.NET Core 服务器中开启 Http2。所以在 appsettings.json 中,这样做。

    "Kestrel": {
        "EndpointDefaults": {
          "Protocols": "Http2"
        }
    

    不安全的 .NET Framework 客户端 + ASP.NET Core 服务器

    • ASP.NET 核心服务器
      1. 删除StartUpConfigureServices(IApplicationBuilder app)中的app.UseHttpsRedirection()app.UseHsts()
      2. 在开发过程中公开不安全的端口,通常为 80 或 5000。
      3. 使用下面的代码在 .NET Framework 客户端中创建不安全的通道。
    var channel = new Channel("localhost", 5001, ChannelCredentials.Insecure);
    

    安全 SSL 连接 .NET Framework 客户端 + ASP.NET Core 服务器

    我通过在客户端中使用 .pem 格式的相同服务器证书使其与 SSL 端口一起使用。

    SslCredentials secureCredentials = new SslCredentials(File.ReadAllText("certificate.pem"));
    var channel = new Channel("localhost", 5001, secureCredentials);
    
    

    稍微解释一下。 VS 2019 中的 ASP.NETCore 模板使用开发证书 pfx 文件位于%AppData%\ASP.NET\Https\ProjectName.pfx 和 密码=%AppData%\Microsoft\UserSecrets\{UserSecretsId}\secrets.json {:Kestrel:Certificates:Development:Password} Value 您可以从ProjectName.csproj 获取UserSecretsId id。这对于每个 ASP.NET Core 项目都是不同的。

    我使用以下命令将 pfx + 密码组合转换为 certificate.pem 文件。

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

    这将提示输入 pfx 密码。使用上面secrets.json的密码。

    为要生成的certificate.pem 提供一些密码(至少 4 个字母)。

    复制此cerificate.pem 供 gRPC .NET Framework 客户端访问和使用

    SslCredentials secureCredentials = new SslCredentials(File.ReadAllText("<DiskLocationTo the Folder>/certificate.pem"))
    var channel = new Channel("localhost", 5001, secureCredentials);
    
    

    请注意,我使用的端口 5001 是我的 ASP.NET Core 应用程序的 SSL 端口。

    适用于生产场景

    使用来自证书签名机构的有效证书,并在 ASP.NET Core Server 和 .NET Framework 客户端中分别使用与 pfxpem 相同的证书。

    【讨论】:

      【解决方案3】:

      this answer 我运气不错。像 OP 一样,我还没有让它远程工作。请记住,IIS 尚不支持 gRPC,因此您还需要寻找替代托管方法。

      【讨论】:

      • 我搞定了。在此处添加我的解决方案作为答案 [stackoverflow.com/a/63041837/6128864] 和此处 [stackoverflow.com/a/63041806/6128864]
      • 另外,如果可能的话,我永远也不想使用 IIS。
      • 为什么你永远不想使用 IIS?它似乎是一个完全有效的反向代理,它提供了功能齐全的 Web 服务器的额外安全性和性能优势
      • 尽可能避免使用windows机器。 IIS 仅适用于 Windows。如果我可以使用 ASP.NET Core 服务器,我总是会选择基于 docker 的分布式系统,它带有一些像 nginx 这样的开源反向代理,而不是 IIS。