Как подключить клиент Grpc (NuGet ›2.33) (.NET Framework) к серверу Grpc.Asp.NetCore (NuGet› 2.31) (.NET 5.0) с помощью HTTPS и моего собственного сертификата?

Сообщение об исключении:

Grpc.Core.RpcException: 'Status (StatusCode = Unavailable, Detail = не удалось подключиться ко всем адресам, DebugException = Grpc.Core.Internal.CoreErrorDetailException: {created: @ 1606657072.668000000, description: Failed to pick subchannel, file: T: \ src \ github \ grpc \ workspace_csharp_ext_windows_x86 \ src \ core \ ext \ filters \ client_channel \ client_channel.cc, file_line: 4166, referenced_errors: [{created: @ 1606657072.668000000, описание: не удалось подключиться ко всем адресам, filec: T: \ sr \ github \ grpc \ workspace_csharp_ext_windows_x86 \ src \ core \ ext \ filters \ client_channel \ lb_policy \ pick_first \ pick_first.cc, file_line: 398, grpc_status: 14}]}) '

Я создал пример на GitHub, который вы можете легко настроить, поиграть и ответить на этот вопрос, если Вам удастся решить проблему.

grpc_certifier_example

...

Я понял, что проблема в моих собственных сертификатах, и я не могу создать свой собственный, который работает, пробовал множество комбинаций.

Я использовал этот пример для создания своих сертификатов: Как включить серверную часть SSL для gRPC?

и протестировал его на этом примере: https://github.com/angelagyang/GRPCProtobufExample


person Community    schedule 29.11.2020    source источник
comment
Нет, в этом случае у него нет ответа.   -  person    schedule 30.11.2020
comment
Собираетесь ли вы использовать аутентификацию клиента (mTLS) или нет? (в заголовке вашего вопроса упоминается только один сертификат)   -  person Peter Wishart    schedule 30.11.2020
comment
Для начала мне нужно любое решение, использующее HTTPS, сначала самое простое, а затем построенное на нем. Мне нужен этот пример для успешного использования HTTPS.   -  person Hrvoje Batrnek    schedule 30.11.2020
comment
Моя цель - иметь приложение с секретом, с помощью которого оно может подключаться к моей службе. Я не хочу, чтобы этот секрет вычислялся вмешательством пользователей, потому что он должен работать до вмешательства любого пользователя и на любом ПК без установки чего-либо до этого устройства, и я также хочу иметь возможность использовать свои собственные сертификаты, которым не доверяет КА, мне это не нужно. Это служба обновления программного обеспечения, решение для обновления программного обеспечения, аналогичное щелчку один раз ...   -  person Hrvoje Batrnek    schedule 30.11.2020
comment
Любой, у кого есть приложение, должен иметь возможность использовать его без какой-либо настройки. Идентичность - это мое приложение и секрет, который он хранит в своем коде. Если соединение безопасное, я не вижу разницы между приложением, предоставляющим какой-либо сертификат в качестве секрета, или паролем. Поправьте меня, если я ошибаюсь. Я также хочу иметь возможность не использовать доверенный сертификат SSL CA, потому что я не хочу его покупать. Загрузите приложение и запустите его с минимальным вмешательством со стороны пользователя.   -  person Hrvoje Batrnek    schedule 01.12.2020
comment
Мне также понадобится служба для создания отчета, и клиентское приложение отправит имя пользователя и пароль этой службе, чтобы она могла определить, имеет ли пользователь право на этот отчет. Я не хочу раздавать какие-либо сертификаты клиентам, потому что он должен быть очень динамичным и гибким, мне просто нужно безопасное соединение, чтобы никто не мог прочитать это имя пользователя и пароль из канала.   -  person Hrvoje Batrnek    schedule 01.12.2020


Ответы (1)


Проблема в сертификате и его CN =. CN =% COMPUTERNAME% должен быть DNS или IP-адресом сервера, в моем случае это должен быть localhost, а сервер должен иметь сертификат с ключом (pfx). Основная проблема заключается в том, что он генерирует исключение без соответствующего объяснения.

Клиент:

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

Сервер:

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

Создание сертификатов:

@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
person Hrvoje Batrnek    schedule 01.12.2020