Bagaimana cara menghubungkan klien Grpc (NuGet> 2.33) (.NET Framework) dengan server Grpc.Asp.NetCore (NuGet> 2.31) (.NET 5.0) menggunakan HTTPS dan sertifikat saya sendiri?

Nov 29 2020

Pesan pengecualian:

Grpc.Core.RpcException: 'Status (StatusCode = "Unavailable", Detail = "gagal terhubung ke semua alamat", DebugException = "Grpc.Core.Internal.CoreErrorDetailException: {" create ":" @ 1606657072.668000000 "," description " : "Gagal memilih sub-saluran", "file": "T: \ src \ github \ grpc \ workspace_csharp_ext_windows_x86 \ src \ core \ ext \ filter \ client_channel \ client_channel.cc", "file_line": 4166, "referenced_errors": [ {"dibuat": "@ 1606657072.668000000", "description": "gagal terhubung ke semua alamat", "file": "T: \ src \ github \ grpc \ workspace_csharp_ext_windows_x86 \ src \ core \ ext \ filter \ client_channel \ lb_policy \ pick_first \ pick_first.cc "," file_line ": 398," grpc_status ": 14}]}") '

Saya telah membuat contoh di GitHub yang dapat Anda sesuaikan dengan mudah, mainkan, dan jawab pertanyaan ini jika Anda berhasil memecahkan masalah.

grpc_certifier_example

...

Saya telah menemukan bahwa masalahnya ada pada sertifikat saya sendiri dan saya tidak dapat membuat karya saya sendiri, mencoba berbagai kombinasi.

Saya telah menggunakan contoh ini untuk membuat sertifikat saya: Bagaimana cara mengaktifkan SSL sisi server untuk gRPC?

dan mengujinya pada contoh ini: https://github.com/angelagyang/GRPCProtobufExample

Jawaban

1 HrvojeBatrnek Dec 01 2020 at 14:32

Masalahnya ada di sertifikat dan CN-nya =. CN =% COMPUTERNAME% harus berupa server DNS atau IP, dalam kasus saya, itu harus localhost dan server harus memiliki sertifikat dengan kunci (pfx). Masalah utamanya adalah ia membuang pengecualian tanpa penjelasan yang relevan.

Klien:

                //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);
                        };
                    });
                });

Pembuatan sertifikat:

@echo off
REM set OPENSSL_CONF=c:\OpenSSL-Win64\bin\openssl.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