在 gRPC 客户端服务器通信中使用 SSL

Use SSL in gRPC client server communication

我对 SSL/TLS 一无所知,我正在尝试按照网上找到的说明在 gRPC 中使用 SSL/TLS 通道。 这是服务器代码:

      std::string server_address("0.0.0.0:50051");
      GreeterServiceImpl service;
    
      grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp ={"a","b"};
      grpc::SslServerCredentialsOptions ssl_opts;
      ssl_opts.pem_root_certs="";
      ssl_opts.pem_key_cert_pairs.push_back(pkcp);
    
      std::shared_ptr<grpc::ServerCredentials> creds;
      creds = grpc::SslServerCredentials(ssl_opts);
    
      ServerBuilder builder;
      builder.AddListeningPort(server_address, creds);
      builder.RegisterService(&service);
      std::unique_ptr<Server> server(builder.BuildAndStart());

服务器无法启动并因以下错误而终止。

E1115 13:00:55.657846941   17129 ssl_transport_security.c:636] Invalid cert chain file.
E1115 13:00:55.657936436   17129 security_connector.c:830]   Handshaker factory creation failed with TSI_INVALID_ARGUMENT.
E1115 13:00:55.657954952   17129 server_secure_chttp2.c:344] {"created":"@1479243655.657946821","description":"Unable to create secure server with credentials of type Ssl.","file":"src/core/ext/transport/chttp2/server/secure/server_secure_chttp2.c","file_line":242,"security_status":1}
Server listening on 0.0.0.0:50051
Segmentation fault (core dumped)

我只想使用 SSL 进行服务器和客户端通信。看起来我在服务器中缺少正确的证书并且相信客户端需要类似的东西。由于我没有任何 SSL 背景知识,如果有人能给我指出有关如何创建这些证书并正确使用 gRPC 通信的示例,那就太好了。

证书的创建方式似乎有问题。我忘记了 Whosebug 中显示如何创建证书的 post。使用该方法并插入密钥和证书以使其工作。

这是我创建密钥 (server.key) 和证书 (server.crt) 的方式。

    mypass="pass123"

    echo Generate server key:
    openssl genrsa -passout pass:$mypass -des3 -out server.key 4096

    echo Generate server signing request:
    openssl req -passin pass:$mypass -new -key server.key -out server.csr -subj  "/C=US/ST=CA/L=SanFrancisco/O=Google/OU=youtube/CN=localhost"

    echo Self-sign server certificate:
    openssl x509 -req -passin pass:$mypass -days 365 -in server.csr -signkey server.key -set_serial 01 -out server.crt

    echo Remove passphrase from server key:
    openssl rsa -passin pass:$mypass -in server.key -out server.key

    rm server.csr

这里注意localhost的使用。在创建客户端通道时应使用相同的方法。 我修改了 grpc 代码库中的示例以使用这些。服务器如下所示。

    std::string server_address("0.0.0.0:50051");
    GreeterServiceImpl service;

    std::string servercert = read_keycert("server.crt");
    std::string serverkey = read_keycert("server.key");

    grpc::SslServerCredentialsOptions::PemKeyCertPair pkcp;
    pkcp.private_key = serverkey;
    pkcp.cert_chain = servercert;

    grpc::SslServerCredentialsOptions ssl_opts;
    ssl_opts.pem_root_certs="";
    ssl_opts.pem_key_cert_pairs.push_back(pkcp);

    std::shared_ptr<grpc::ServerCredentials> creds;
    creds = grpc::SslServerCredentials(ssl_opts);

    ServerBuilder builder;
    builder.AddListeningPort(server_address, creds);
    builder.RegisterService(&service);
    std::unique_ptr<Server> server(builder.BuildAndStart());
    server->Wait();

客户端只需要证书。以下是它在我的案例中的使用方式。

    std::string cacert = read_keycert("server.crt");
    grpc::SslCredentialsOptions ssl_opts;
    ssl_opts.pem_root_certs=cacert;

    auto ssl_creds = grpc::SslCredentials(ssl_opts);
    GreeterClient greeter(grpc::CreateChannel("localhost:50051", ssl_creds));

生成和使用密钥和证书的方式在每个用例中都不同。我认为如果两台服务器进行通信,那么它们可能会有所不同。不确定。希望这可以帮助一些新手开始使用 gRPC C++ 中的安全 SSL/TLS。