Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
502 views
in Technique[技术] by (71.8m points)

c# - How to connect Grpc (NuGet >2.33) client (.NET Framework) with Grpc.Asp.NetCore (NuGet >2.31) server (.NET 5.0) using HTTPS and my own certificate?

Exception message:

Grpc.Core.RpcException: 'Status(StatusCode="Unavailable", Detail="failed to connect to all addresses", DebugException="Grpc.Core.Internal.CoreErrorDetailException: {"created":"@1606657072.668000000","description":"Failed to pick subchannel","file":"T:srcgithubgrpcworkspace_csharp_ext_windows_x86srccoreextfiltersclient_channelclient_channel.cc","file_line":4166,"referenced_errors":[{"created":"@1606657072.668000000","description":"failed to connect to all addresses","file":"T:srcgithubgrpcworkspace_csharp_ext_windows_x86srccoreextfiltersclient_channellb_policypick_firstpick_first.cc","file_line":398,"grpc_status":14}]}")'

I've created an example on GitHub which you can easily tweak, play with, and answer this question if you succeed to solve the problem.

grpc_certifier_example

...

I've figured out that the problem is in my own certificates and I am unable to create my own that work, tried numerous combinations.

I've used this example to generate my certificates: How to enable server side SSL for gRPC?

and tested it on this example: https://github.com/angelagyang/GRPCProtobufExample

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The problem is in the certificate and its CN=. CN=%COMPUTERNAME% must be server DNS or IP, in my case, it had to be localhost and the server needs to have a certificate with the key (pfx). The main problem is that it throws the exception with no relevant explanation.

Client:

                //THIS IS YOUR CLIENT'S CERTIFICATE AND IT'S KEY
                var keyCertPair = new KeyCertificatePair(File.ReadAllText($"{rootDir}/samplecert.pem.txt"), File.ReadAllText($"{rootDir}/samplecert.key.txt"));
                //GetRootCertificates() GETS THE CA CERTIFICATE, NOT THE CLIENT CERTIFICATE NOR SERVER CERTIFICATE
                var channelCreds = new SslCredentials(GetRootCertificates(), keyCertPair);
                //YOU DON'T EVEN NEED TO PROVIDE KeyCertificatePair, IT WORKS WITH JUST A CA ROOT
                var channelCreds = new SslCredentials(GetRootCertificates());

Server:

                //LoadSSLCertificate() GETS THE SERVER CERTIFICATE
                var sslCertificate = LoadSSLCertificate(); 
                o.ListenAnyIP(5001, listenOptions =>
                {
                    listenOptions.UseHttps(sslCertificate, httpsOptions =>
                    {
                        httpsOptions.SslProtocols = SslProtocols.Tls12;
                        httpsOptions.ClientCertificateMode = ClientCertificateMode.NoCertificate;
                        httpsOptions.ClientCertificateValidation = (certificate, chain, errors) =>
                        {
                            return true;
                            //return certificate.Thumbprint.Equals(_clientThumbprint, StringComparison.OrdinalIgnoreCase);
                        };
                    });
                });

Certificates creation:

@echo off
REM set OPENSSL_CONF=c:OpenSSL-Win64inopenssl.cfg   

echo Generate CA key:
openssl genrsa -passout pass:1111 -des3 -out ca.key 4096

echo Generate CA certificate:
openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=MyRootCA"

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

echo Generate server signing request:
openssl req -passin pass:1111 -new -key server.key -out server.csr -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=%COMPUTERNAME%"

echo Self-sign server certificate:
openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt

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

echo Generate client key
openssl genrsa -passout pass:1111 -des3 -out client.key 4096

echo Generate client signing request:
openssl req -passin pass:1111 -new -key client.key -out client.csr -subj  "/C=US/ST=CA/L=Cupertino/O=YourCompany/OU=YourApp/CN=%CLIENT-COMPUTERNAME%"

echo Self-sign client certificate:
openssl x509 -passin pass:1111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt

echo Remove passphrase from client key:
openssl rsa -passin pass:1111 -in client.key -out client.key

echo Create server.pfx file:
openssl pkcs12 -export -passout pass:1111 -out server.pfx -inkey server.key -in server.crt

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...