Comment connecter le client Grpc (NuGet> 2.33) (.NET Framework) au serveur Grpc.Asp.NetCore (NuGet> 2.31) (.NET 5.0) en utilisant HTTPS et mon propre certificat?
Message d'exception:
Grpc.Core.RpcException: 'Status (StatusCode = "Unavailable", Detail = "échec de la connexion à toutes les adresses", DebugException = "Grpc.Core.Internal.CoreErrorDetailException: {" created ":" @ 1606657072.668000000 "," description " : "Impossible de sélectionner le sous-canal", "fichier": "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", "description": "n'a pas réussi à se connecter à toutes les adresses", "file": "T: \ src \ 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}]}") '
J'ai créé un exemple sur GitHub avec lequel vous pouvez facilement modifier, jouer avec et répondre à cette question si vous réussissez à résoudre le problème.
grpc_certifier_example
...
J'ai compris que le problème venait de mes propres certificats et je suis incapable de créer les miens qui fonctionnent, j'ai essayé de nombreuses combinaisons.
J'ai utilisé cet exemple pour générer mes certificats: Comment activer SSL côté serveur pour gRPC?
et testé sur cet exemple: https://github.com/angelagyang/GRPCProtobufExample
Réponses
Le problème est dans le certificat et son CN =. CN =% COMPUTERNAME% doit être un serveur DNS ou IP, dans mon cas, il devait être localhost et le serveur doit avoir un certificat avec la clé (pfx). Le principal problème est qu'il lève l'exception sans explication pertinente.
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());
Serveur:
//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);
};
});
});
Création de certificats:
@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