2

We're doing an integration with Google via RESTful API and I need to sign a payload of a JWT with RSA-SHA256 and all I have is a Private Key as a string, that looks like

-----BEGIN PRIVATE KEY-----
MIIEvgIBfADANBg9qhkdsiG9w0BAQEFAASCBKgw
......
-----END PRIVATE KEY-----

I've been looking everywhere for a solution, but everyone's talking about X509Certificate2 which needs a p12 file, or some Certificates. Now I don't have either of those, I only have a string that is the private key.

Google recommends https://jwt.io/ and it works with the key string, but well, I need my CODE to do it. There are 3 libraries listed in the page:

  1. One of them belongs to Microsoft and has absolutely no documentation.
  2. Another one is using X509Certificate2 or specifically for string keys only has a link to this place http://www.donaldsbaconbytes.com/2016/08/create-jwt-with-a-private-rsa-key/ which uses some Certificate files I don't have, making it a wrong and unhelpful link to begin with.
  3. Same creators of #2 have another lib, but it's for phones and it actually has a method for RSA256 signing which takes private key as a string of exactly my format.

So my question is - is there some working solution for my case? Because I can't believe that no one else has integrations with Google.

giedriusx3
  • 123
  • 2
  • 8
  • How long is the key exactly? There is more on those `....` right? – bommelding Oct 09 '18 at 08:15
  • You can turn it into bytes with Convert.FromBase64String and then see if the X509 class likes it as rawData. – bommelding Oct 09 '18 at 08:17
  • bommelding, the whole key (with the "-----BEGIN PRIVATE KEY----" and the ending) is characters 1676 long – giedriusx3 Oct 09 '18 at 08:22
  • That would be about 1k bytes, long enough for a certificate. Now find out what format it is. Inspecting the bytes in Visual studio could be a quick start. – bommelding Oct 09 '18 at 08:31
  • @bommelding: It's almost certainly a PKCS8 private key, not a certificate. – President James K. Polk Oct 09 '18 at 14:05
  • https://stackoverflow.com/questions/48905438/digital-signature-in-c-sharp-without-using-bouncycastle/48911283#48911283?newreg=30481101ca2d495482bf0c65e5fdbbd8 – cs tay May 04 '22 at 04:33
  • Please refer here: https://stackoverflow.com/questions/48905438/digital-signature-in-c-sharp-without-using-bouncycastle/48911283#48911283?newreg=30481101ca2d495482bf0c65e5fdbbd8 – cs tay May 04 '22 at 04:34

1 Answers1

2

I know of a way to convert this to a pfx that you can use in C#.

First, install OpenSSL if you haven't already. (You could get the latest "Win64 OpenSSL v#.#.#x Light" from http://slproweb.com/products/Win32OpenSSL.html, though I take no responsibility for this source.)

You may want to add "C:\Program Files\OpenSSL\bin\" to your account's path variable, so that "openssl.exe" can be used from anywhere in the command line.

In a command window, navigate to where your private key file is. Let's call it "priv.key". Issue the following two commands, ignoring the comments:

# Create public self-signed certificate CRT file (with 7000yr validity) from private key (may leave all info empty)
openssl req -x509 -sha256 -new -key priv.pem -out pub.crt -days 2555000

# Combine into PFX container (encrypted with AES-256) (certificate needs to be included for .NET to read successfully)
openssl pkcs12 -export -aes256 -CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" -inkey priv.pem -in pub.crt -out priv.pfx

Note that on the last command, I am creating an encrypted pfx (this is optional - I believe you could replace -aes256 by -nodes to skip it), and I am configuring the cryptographic provider such that the key can be used for SHA256 operations without C# complaining.

You now have a pfx file that you can load using the constructor of X509Certificate2.

I tend to use this cheat sheet for common OpenSSL commands: https://www.sslshopper.com/article-most-common-openssl-commands.html

Timo
  • 7,992
  • 4
  • 49
  • 67