2

I have an Apache (xampp/wamp) server that provides a SSL connection on port 443. It uses two certificate files: server.cert and server.key when the latter conains the private key.

I have another server configured to listen to requests on port 843 (flash policy stuff) and response to a certain request with some text reply written in C# which runs separately.

In order to achieve SSL connectivity, i use a flex object called SecureSocket which allowes that, however, it uses the original servers certificate in order to encrypt the request.

My goal is to teach my 843 C# server to decrypt the sent data and encrypt the reply and for this i'm using the X509Certificate object in C#.

However, since the pub and priv keys are on different files, i'm getting FALSE on the following:

string text = System.IO.File.ReadAllText(@"C:\xampp\apache\conf\ssl.crt\server.crt");
UTF8Encoding encoding = new System.Text.UTF8Encoding();
byte[] byteCert = encoding.GetBytes(text);
X509Certificate2 uberCert = new X509Certificate2();
uberCert.Import(byteCert);
Console.WriteLine("Has privateKey:" + uberCert.HasPrivateKey.ToString());
Console.WriteLine("PrivateKey: \n" + uberCert.PrivateKey);

Obviously, the False on uberCert.HasPrivateKey comes from the fact that the private key is on a different file, so my questions are:

1.How can i read the private key using the X509CErtificate2 object? 2.How can i use the public key in order to decrypt the received message and how to re-encrypt it with the private key (in order to send the encrypted response back) ?

Thanks in advance,

Mike.

svick
  • 236,525
  • 50
  • 385
  • 514
silicakes
  • 6,364
  • 3
  • 28
  • 39

3 Answers3

1

I've created a small helper NuGet package (based on opensslkey) to create a X509 certificate based on public key and private (rsa) key.

// Generate with: openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout private.key -out certificate_pub.crt
string certificateText = File.ReadAllText("certificate_pub.crt");
string privateKeyText = File.ReadAllText("private.key");

ICertificateProvider provider = new CertificateFromFileProvider(certificateText, privateKeyText);
X509Certificate2 certificate = provider.Certificate;

// Example: use the PrivateKey from the certificate above for signing a JWT token using Jose.Jwt:
string token = Jose.JWT.Encode(payload, certificate.PrivateKey, JwsAlgorithm.RS256);

See NuGet and Github-project for functionality and code-examples.

Stef Heyenrath
  • 9,335
  • 12
  • 66
  • 121
0

The private key is likely PEM encoded PKCS#8 structure.

The Mono project provides code to read this format (among other) in the Mono.Security.dll assembly. This assembly is purely managed and will work on Windows, Linux or OSX.

poupou
  • 43,413
  • 6
  • 77
  • 174
0

You can't in straight .NET.

You can either use BouncyCastle (see this answer: How to read a PEM RSA private key from .NET) or use a PKCS12 container instead for the username + password, which you can create using OpenSSL's tools from the PEM files.

Community
  • 1
  • 1
Joe
  • 41,484
  • 20
  • 104
  • 125
  • Hi @Joe, I've done the following: `X509Certificate2 uberCert = new X509Certificate2(@"C:\xampp\apache\conf\server.pfx","qwe123",X509KeyStorageFlags.MachineKeySet);` after combining both keys into a single pfx file using openssl. It replies with true if i check whether a private key exists, yet i don't know how use it in order to decipher my not Base64 encoded requests. When using the link you've provided, all i'm getting are exceptions. any tips? – silicakes Feb 22 '12 at 10:17