Interoperability between RSACryptoServiceProvider and openSSL
Asked Answered
W

2

12

I've used the .NET class RSACryptoServiceProvider to get a keypair:

using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
  File.WriteAllText ("PublicKeyOnly.xml", rsa.ToXmlString (false));
  File.WriteAllText ("PublicPrivate.xml", rsa.ToXmlString (true));
}

Now, I would like to use this with openSSH, but the key format looks nothing alike. Does anyone know how to convert both the public and private keys to files that openSSH can use?

Thanks!

Wasteful answered 15/7, 2010 at 21:42 Comment(1)
#497928 looks like it should work, no?Chenault
J
8

I really needed to achieve Openssl interoperability with RSACryptoServiceProvider, so that I could implement a software licence key system (Ref).

I needed to be able to create the private and public keys in Linux using openssl so that they could later be used for license management in a PHP web application. Yet, also use them as the basis of an RSA signature license system in a VB.Net applciation.

After a week of searching, I eventually discovered that this is perfectly possible, so I thought I would share it.

Start on Linux (or any other useful OS) and use openssl to create a private key (private.pem), a public key (public.pem), a certificate (certificate.crt) and a Personal Information Exchange File (certificate.pfx). Don't worry about the CN and emailAddress fields, the certificate and pfx files are only being used as a vehicle to get the public or private key into the RSACryptoServiceProvider object.

openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -pubout
openssl req -nodes -x509 -days 3650 -subj '/CN=www.example.com/[email protected]' -new -key private.pem -out certificate.crt
openssl pkcs12 -export -out certificate.pfx -inkey private.pem -in certificate.crt

Now to get the private key into the code:

Dim cert As New X509Certificate2("certificate.pfx", "", X509KeyStorageFlags.Exportable)
Dim rsaProvider As RSACryptoServiceProvider = DirectCast(cert.PrivateKey, RSACryptoServiceProvider)

If you need the private key or public key try this:

msgbox(rsaProvider.ToXmlString(True))  'Private key in XML format
msgbox(rsaProvider.ToXmlString(False)) 'Public key in XML format

To get the public key into the code:

Dim cert As New X509Certificate2("certificate.crt")
Dim rsaProvider As RSACryptoServiceProvider = DirectCast(cert.PublicKey.Key, RSACryptoServiceProvider)

If you need the public key try this:

msgbox(rsaProvider.ToXmlString(False))  'Public key in XML format

More to come .....

Jones answered 28/5, 2012 at 13:46 Comment(0)
L
2

This blog post on using OpenSSL and RSACryptoServiceProvider states that it is possible, but the author ended up using the Chilkat RSA Library to ultimately interoperate with OpenSSL from within C#. The PEM format is not supported in the .NET world so you could use this library from JavaScience called OpenSSLKey.cs; however, as the author of the blog post mentions they had problems due to this (quoted):

OpenSSL: Can only sign small bits of data that fit within a single block. The data is padded and signed. The reverse is called "verify" and in that case the data is "unsigned" and then unpadded and the original data is returned.

[Windows]: Can sign any amount of data. The Sign* methods first hash the data and then the hash is padded and signed. The Verify* methods expect three inputs: the original data, a hash algorithm name, and the signature data. The original data is hashed and the result of unsigning/unpadding is compared with the hash of the original data.

So I recommend you go with the Chilkat RSA library.

Laughlin answered 6/7, 2011 at 20:53 Comment(1)
No, I think OpenSSL can sign any amount of data, also.. you use a combination of EVP_SignInit, zero or many EVP_SignUpdate's and an EVP_SignFinal. It's not too hard to implement ICryptoTransform and other .NET Crypto interfaces on top of an OpenSSL native wrapper such as openssl-net on sourceforge.Multifoil

© 2022 - 2024 — McMap. All rights reserved.