0

Can I use C# Full .NET Framework Client with C# .NET core client with a secured Channel.?

Can you lead me to some examples where this is done? I could not find anywhere if this can be done or It Cannot be done.

Detail: I made an example using .NET Framework client with Grpc C# Github as the reference and .NET Core client with this example from Grpc dotnet as a the reference. I was able to establish an insecure communication channel with

new Channel("127.0.0.1", 5000, ChannelCredentials.Insecure)

and the Non-Https port opened in 5000 in the ASP.NET Core server.

When I try to connect with

var channel = new Channel("127.0.0.1", 5001, new SslCredentials());

to the Https port 5000 in the ASP.NET Core ServerI

How can I use a secure channel to communicate. I want to use the same pfx + password combination.

Jins Peter
  • 2,368
  • 1
  • 18
  • 37

3 Answers3

3

I'm posting this answer for the sake of next person looking for the solution. I have posted my solution in similar use case question in SO after I got it working here and here

-- Below is copied from My own answer.

Over SSL or not, you need to turn on Http2 in ASP.NET Core server. So in appsettings.json, do this.

"Kestrel": {
    "EndpointDefaults": {
      "Protocols": "Http2"
    }

Insecure .NET Framework Client + ASP.NET Core Server

  • ASP.NET Core Server
    1. Remove app.UseHttpsRedirection() and app.UseHsts() in the StartUp class ConfigureServices(IApplicationBuilder app);
    2. Expose the insecure port, typically 80 or 5000 during development.
    3. Use the code below to create insecure channel in .NET Framework client.
var channel = new Channel("localhost", 5001, ChannelCredentials.Insecure);

Secure SSL connection .NET Framework Client + ASP.NET Core Server

I got it working with SSL port by using the same Server's certificate in .pem format in the client.

SslCredentials secureCredentials = new SslCredentials(File.ReadAllText("certificate.pem"));
var channel = new Channel("localhost", 5001, secureCredentials);

A bit of explanation. An ASP.NETCore template in VS 2019 uses a development certificate with pfx file at %AppData%\ASP.NET\Https\ProjectName.pfx and password = %AppData%\Microsoft\UserSecrets\{UserSecretsId}\secrets.json {:Kestrel:Certificates:Development:Password} Value You can get the UserSecretsId id from the ProjectName.csproj. This will be different for each ASP.NET Core Project.

I used the below command to convert the pfx + password combination to a certificate.pem file.

openssl pkcs12 -in "<DiskLocationOfPfx>\ProjectName.pfx" -out "<TargetLocation>\certifcate.pem" -clcerts

This will prompt for the pfx password. Use the password from the above secrets.json.

Give some passphrase for the certificate.pem to be generated(At least 4 letter).

Copy this cerificate.pem for the gRPC .NET Framework client to access and use in

SslCredentials secureCredentials = new SslCredentials(File.ReadAllText("<DiskLocationTo the Folder>/certificate.pem"))
var channel = new Channel("localhost", 5001, secureCredentials);

Note that port 5001 I used is the SSL port of my ASP.NET Core application.

For Production Scenarios

Use a valid certificate from certificate signing authority and use same certificate in ASP.NET Core Server and .NET Framework client as pfx and pem respectively.

Jins Peter
  • 2,368
  • 1
  • 18
  • 37
1

Check out my question and answer here. I created a basic sample that may be helpful: https://github.com/angelagyang/GRPCProtobufExample

You can configure a client certificate by creating a KeyCertificatePair to pass into SslCredentials. You will need three PEM-encoded strings:

  1. PEM-encoded client certificate chain
  2. PEM-encoded private key
  3. PEM-encoded server SSL certificate.

Here is an example setup:

var keyCertPair = new KeyCertificatePair(clientsslcert.pem, privatekey.pem); 
var channelCreds = new SslCredentials(serversslcert.pem, keyCertPair);

For testing purposes, I found these test PEMs helpful. I used OpenSSL to convert PFX to PEM format. Additionally, this post talks a bit more about the different PEM strings and why the client needs to explicitly trust the server.

Angela Yang
  • 348
  • 3
  • 9
  • This is a good solution, But I would want to reduce the code to minimum as possible. I got this working without the keyCertPair part, but reading the pem as text. Please check out my solution. – Jins Peter Jul 24 '20 at 21:22
  • 2
    Glad to hear it! The KeyCertificatePair only needs to be used if you want to implement client certificate verification (i.e. if the server wants to verify the certificate of the client for an added layer of security). – Angela Yang Jul 25 '20 at 00:41
  • I found a way without needing to store the pem on the client side, maybe it's useful for other people as well: https://stackoverflow.com/a/66041094/727250 – rene_r Feb 04 '21 at 07:46
0

I had some luck with this answer. Like the OP, I haven't made it work remotely yet. Keep in mind that gRPC isn't supported by IIS yet, so you'll need to find and alternative hosting method too.

  • I got it working. Added my solution as answer here [https://stackoverflow.com/a/63041837/6128864] and here[https://stackoverflow.com/a/63041806/6128864] – Jins Peter Jul 24 '20 at 21:07
  • Also, I wouldn't ever want to use IIS if possible. – Jins Peter Jul 24 '20 at 21:18
  • Why would you never want to use IIS? It seems like a perfectly valid reverse proxy, and it provides the additional security and performance benefits of a fully featured web server – dsestrich Jul 27 '20 at 16:02
  • To avoid using windows machine if possible. IIS is windows only. If I could use ASP.NET Core server, I would always go for docker based distributed system with some opensource reverse proxy like nginx than an IIS. – Jins Peter Jul 28 '20 at 03:28