0

How can I properly create the RSACryptoServiceProvider object using an RSA private key file? I generated an RSA private key and exported it to a p12 file on OSX using the methods:

openssl genrsa -out rsakey.pem 2048 openssl pkcs12 -export -out rsakey.p12 -inkey rsakey.pem -nocerts 

In my C# code, which runs on a Windows laptop, I am getting an error trying to instantiate the X509Certificate2 object so that I can grab the private key as an RSACryptoServiceProvider object out of it:

var privateKey = new X509Certificate2(p12_file, "pass", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet).PrivateKey as RSACryptoServiceProvider; 

CryptographicException: The parameter is incorrect.

Below is the entire C# code for reference. Note that I am just trying to get the private key as an RSACryptoServiceProvider object by following the docs for the X509Certificate2 class.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.IO; using System.Net; using System.Security; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Globalization; using Jose; using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { string p12_file = @"C:\Root\rsakey.p12"; DateTime issued = DateTime.Now; DateTime expire = DateTime.Now.AddHours(10); var payload = new Dictionary<string, object>() { { "iss", "auth0_user"}, { "exp", ToUnixTime(expire).ToString() } }; var privateKey = new X509Certificate2(p12_file, "pass", X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet).PrivateKey as RSACryptoServiceProvider; string token = Jose.JWT.Encode(payload, privateKey, JwsAlgorithm.RS256); Console.WriteLine(token); } static long ToUnixTime(DateTime dateTime) { return (int)(dateTime.ToUniversalTime().Subtract(new DateTime(1970, 1, 1))).TotalSeconds; } } } 

UPDATE: I tried to create my self-signed cert using

openssl req -key rsakey.pem -new -out domain.crt 

and then wrapping it into a p12:

openssl pkcs12 -export -out rsakey.p12 -in rsakey.pem -certfile domain.crt 

but the command just hangs forever until I kill it.

2 Answers 2

1

.NET has no built-in functionality for reading private keys (or public keys, for that matter) which are not associated with certificates.

Your easiest fix is to wrap the new RSA key in a self-signed cert, and then put both the cert and the private key into the .p12 file.

The alternatives are to manually parse the private key file/blob and build an RSAParameters structure; or to use a 3rd party library which can do that for you.

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your advice. How do I achieve either of those options? I am not familiar.
Self-parsing would involve finding the appropriate RFCs to find the data structures, then decoding DER. A 3rd party library is a pretty wide open area. But the easiest solution is openssl req -new -x509 -key rsakey.pem -out selfsigned.cer (and just accept all the defaults when prompted). (and replace -nocerts with -in selfsigned.cer in your .p12 creation). Then call GetRSAPrivateKey() or GetRSAPublicKey() on the cert.
I tried different variants, but this finally works. Thank you
0

Since your P12 file does not contain an X509 Certificate, X509Certificate2 does not interpret the file as the proper input.

1 Comment

I really just want the private key as an RSACryptoServiceProvider object. How can I achieve that?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.