首页 > 解决方案 > 我可以使用自签名证书在 .NET 中加密 gRPC

问题描述

我花了相当多的时间试图研究这个,但不能真正找到一个确凿的答案。我可以找到一年前的帖子,声称这在 grpc 的 C#/.NET 实现中不起作用。

我已经使用 openssl 创建了一个自签名证书,如下所示:

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 3650

我创建了凭据:

var keyCertPair = new KeyCertificatePair(File.ReadAllText(@"c:\temp\cert.pem"), File.ReadAllText(@"c:\temp\key.pem"));

var credentials = new SslServerCredentials(new[] { keyCertPair });

var server = new Grpc.Core.Server
 {
      Services = { ServerVersionGrpcService.BindService(serverVersionService).Intercept(exceptionInterceptor) },
      Ports = { new ServerPort("localhost", 5001, credentials) }
};

server.Start();

但是现在我的服务抛出异常

System.IO.IOException: '无法绑定端口 "localhost:5001"

我在这里想念什么?

标签: c#.netgrpc

解决方案


以下对我有用,假设一切都在${PWD}/app

  1. 创建自签名证书|密钥:
openssl req \
-x509 \
-newkey rsa:2048 \
-keyout ./app/localhost.key \
-out ./app/localhost.crt \
-nodes \
-days 365 \
-subj "/CN=localhost"
  1. 运行

dotnet在容器中使用:

GRPC="50052"
docker run \
--rm --interactive --tty \
--volume=${PWD}/app:/app \
--workdir=/app \
--publish=${GRPC}:50051 \
mcr.microsoft.com/dotnet/sdk:5.0 \
  bash

和:

dotnet new console

# Optional
dotnet add package Google.Protobuf --version 3.8.0
dotnet add package Grpc --version 2.23.0
dotnet add package Grpc.Core --version 2.23.0
dotnet add package Grpc.Tools --version 2.23.0
  1. 代码

您的代码,但使用 repo 的greet.proto示例:

using Grpc.Core;
using System;
using System.Threading.Tasks;
using System.IO;

namespace app {
  public class GreeterService: Greeter.GreeterBase {
    public override Task<HelloReply> SayHello(
      HelloRequest request,
      ServerCallContext context
    ) {
      Console.WriteLine("[SayHello] Entered");
      return Task.FromResult(new HelloReply {
        Message = "Hello " + request.Name
      });
    }
  }
  class Program {
    const int Port = 50051;
    static void Main(string[] args) {
      var keyCertPair = new KeyCertificatePair(
        File.ReadAllText(@"localhost.crt"),
        File.ReadAllText(@"localhost.key")
      );

      var credentials = new SslServerCredentials(new []{
        keyCertPair
      });

      var server = new Server {
        Services = { Greeter.BindService(new GreeterService()) },
          Ports = { new ServerPort("0.0.0.0", Port, credentials) }
      };

      server.Start();

      Console.WriteLine("gRPC Server [:" + Port + "]");
      Console.WriteLine("Press any key to stop the server...");
      Console.ReadKey();

      server.ShutdownAsync().Wait();
    }
  }
}

和:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Google.Protobuf" Version="3.8.0" />
    <PackageReference Include="Grpc" Version="2.23.0" />
    <PackageReference Include="Grpc.Core" Version="2.23.0" />
    <PackageReference Include="Grpc.Tools" Version="2.23.0" PrivateAssets="All" />
  </ItemGroup>

  <ItemGroup>
    <Protobuf Include="greet.proto" />
  </ItemGroup>

</Project>
  1. 添加libc-dev

根据此评论

您需要:

apt update && apt -y install libc-dev
  1. 测试:
GRPC="50052"

grpcurl \
-insecure \
-cert app/localhost.crt \
-key app/localhost.key \
-proto app/greet.proto \
-d '{"name":"Freddie"}' \
localhost:${GRPC} \
Greeter.SayHello

产量:

{
  "message": "Hello Freddie"
}

推荐阅读