2

I have an RSA private key loaded in an RSACryptoServiceProvider object. I need to export this to a .pvk file for use with SQL Server.

Is there a way to do this from within c#? I see it's possible using openssl... https://stackoverflow.com/a/51207929/5924962

This is the only documentation I could find on the pvk file format: https://web.archive.org/web/20141117214716/http://www.drh-consultancy.demon.co.uk/pvk.html

fafrd
  • 1,017
  • 13
  • 17
  • Google search for "rsacryptoserviceprovider export key" led me to https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.exportparameters(v=vs.110).aspx – Pankaj Kapare Aug 08 '18 at 15:55
  • 1
    Sure, but I need .pvk file format specifically. it's a proprietary microsoft format. – fafrd Aug 08 '18 at 15:56

2 Answers2

2

Mono project has an open source implementation of the PVK format,

https://github.com/mono/mono/blob/master/mcs/class/Mono.Security/Mono.Security.Authenticode/PrivateKey.cs

Note the Mono.Security NuGet package is not official.

Lex Li
  • 60,503
  • 9
  • 116
  • 147
1

If you look at the output of RSACryptoServiceProvider.ExportCspBlob you'll see that it starts with the same sequence of bytes as offset 24 of an unencrypted PVK file. So a PVK file is just the CSP blob with a header:

using (var output = new BinaryWriter(File.Create("rsa.pvk")))
{
    output.Write(0xB0B5F11Eu);  // PVK magic number
    output.Write(0u);
    output.Write(1u);           // KEYTYPE_KEYX for RSA
    output.Write(0u);           // not encrypted
    output.Write(0u);           // encryption salt length

    var cspBlob = rsaCSP.ExportCspBlob(true);
    output.Write((uint)cspBlob.Length);
    output.Write(cspBlob);
}

I've verified that OpenSSL will read this

openssl rsa -in rsa.pvk -inform PVK

and will generate the same PEM private key export as the code in this answer that generates the PEM private key directly from the RSACryptoServiceProvider.

Rup
  • 33,765
  • 9
  • 83
  • 112
  • Of course I didn't see this straight away. I'd written most of a PVK exporter based on [the OpenSSL source](https://github.com/openssl/openssl/blob/master/crypto/pem/pvkfmt.c), and then wondered if I could use ExportCspBlob to verify my output. Bah. – Rup Aug 08 '18 at 22:47
  • `Mono.Security` also has an implementation https://github.com/mono/mono/blob/master/mcs/class/Mono.Security/Mono.Security.Authenticode/PrivateKey.cs – Lex Li Aug 08 '18 at 23:17
  • @LexLi That's neat, and probably worth its own answer? It adds password protection that my version doesn't have, and supports big endian systems too. (Mine's certainly simpler though.) it does back up my findings that the core of the file is a CAPI blob, though: the actual key export is in [CryptoConvert.ToCapiPrivateKeyBlob](https://github.com/mono/mono/blob/master/mcs/class/Mono.Security/Mono.Security.Cryptography/CryptoConvert.cs#L282). – Rup Aug 08 '18 at 23:27