Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate self signed RSA-2048-SHA-256 certificate PFX file using openSSL

I am trying to create a self signed RSA-2048-SHA-256 certificate PFX file, in order to use it for data signing in my WCF requests.

I used some openSSL examples in order to create a certificate PFX file, but even though I set the SHA algorithm to 256, when I load it in my .net app, I see that this certificate's private key, has these settings:

KeyExchangeAlgorithm = RSA-PKCS1-KeyEx

SignatureAlgorithm = http://www.w3.org/2000/09/xmldsig#rsa-sha1

and when I use the code below in order to consume this certificate, I am getting "Invalid algorithm specified exception", but if I change the SHA256CryptoServiceProvider to SHA1CryptoServiceProvider everything works fine.

string msg = "This is my test message";

X509Certificate2 privateCert = new X509Certificate2("C:\\TEMP\\private.pfx", "12345");

byte[] signature = (privateCert.PrivateKey as RSACryptoServiceProvider).SignData(new UTF8Encoding().GetBytes(msg), new SHA256CryptoServiceProvider());

I can only assume that my certificate file was not created with SHA256, but instead with some kind of default SHA1 algorithm.

Those are the steps I used in order to create my certificate:

  1. openssl req -x509 -days 365 -newkey rsa:2048 -sha256 -keyout key.pem -out cert.pem
  2. openssl pkcs12 -export -in cert.pem -inkey key.pem -out private.pfx

What am I doing wrong?

like image 783
Alex Avatar asked Nov 08 '22 23:11

Alex


1 Answers

What am I doing wrong?

Believing that those two properties have meaning :).

The two values you're seeing are hard-coded into RSACryptoServiceProvider. Other RSA types (such as RSACng) have different, less confusing, hard-coded values.

The problem is that a key doesn't have either of those attributes. A key can be used for multiple purposes (though NIST recommends against it). A TLS session (or EnvelopedCMS document, etc) can have a key exchange algorithm. A certificate, SignedCMS document, or other such material can have a signature (and thus a signature algorithm).

To know that your certificate was signed with RSA-PKCS1-SHA256 you need to look at X509Certificate2.SignatureAlgorithm.

switch (cert.SignatureAlgorithm.Value)
{
    case "1.2.840.113549.1.1.4":
        return "RSA-PKCS1-MD5";
    case "1.2.840.113549.1.1.5";
        return "RSA-PKCS1-SHA1";
    case "1.2.840.113549.1.1.11";
        return "RSA-PKCS1-SHA2-256"; // Winner
    case "1.2.840.113549.1.1.12":
        return "RSA-PKCS1-SHA2-384";
    case "1.2.840.113549.1.1.13":
        return "RSA-PKCS1-SHA2-512";
    default:
        throw new SomethingFromTheFutureOrMaybeNotRSAException();
}
like image 62
bartonjs Avatar answered Nov 15 '22 07:11

bartonjs