我创建了一个 grpc 服务器:
grpc::ServerBuilder builder;
grpc::SslServerCredentialsOptions credential_options;
credential_options.force_client_auth = true;
const std::string private_key = read_file("server.key");
const std::string cert_chain = read_file("server.crt");
credential_options.pem_key_cert_pairs.push_back({private_key, cert_chain});
auto channel_credentials = grpc::SslServerCredentials( credential_options );
builder.AddListeningPort(StateService::instance().ipAddress(), channel_credentials);
builder.RegisterService(grpcLocalService_.get());
server_ = builder.BuildAndStart();
我用脚本创建了一个密钥和一个证书:
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
当我运行应用程序时,我得到以下信息:
E0813 19:24:39.571705892 21058 ssl_transport_security.c:628] 证书链文件无效。
E0813 19:24:39.571727037 21058 security_connector.c:893] 握手器工厂创建失败,出现 TSI_INVALID_ARGUMENT。
E0813 19:24:39.571736766 21058 server_secure_chttp2.c:96] {"created":"@1597321479.571730594","description":"无法使用 Ssl 类型的凭据创建安全服务器。","file":"src/core/ ext/transport/chttp2/server/secure/server_secure_chttp2.c","file_line":75,"security_status":1}
我是否正确理解grpc::SslServerCredentialsOptions::PemKeyCertPair
您需要传递文件的内容.key
和.crt
而不是文件名?如果是这样,应该如何阅读它们?
-----BEGIN CERTIFICATE-----
MIIFMDCCAxgCAQEwDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCVVMxCzAJBgNV
...// лишние строки убрал для краткости
BAgMAkNBMQ4wDAYDVQQHDAVUb21zazEOMAwGA1UECgwFRWxlc3kxDjAMBgNVBAsM
-----END CERTIFICATE-----
是否跳过第一行和最后一行?
但无论如何,错误仍然是一样的。 Handshaker factory creation failed with TSI_INVALID_ARGUMENT.
密钥和证书文件的
grpc::SslServerCredentialOptions::PemKeyCertPair
内容必须完整地传递给结构。如问题评论中所述,您需要将根证书设置为
credential_options.pem_root_certs
. 我使用从这里获取的脚本生成了证书和密钥