RSACryptoServiceProvider – Create a SSH-RSA Public Key

How to Generate a Public SSH-RSA key & get it to match Putty Gen’s RSA Keys!
Personal Blog: Not representative of Microsoft.

I’ve found that for some reason when generating a 3072 Bit RSA key, PuttyGen would generate a different RSA public key than mine.

After researching, I found that it seems in the source code (link) of the Putty Gen Program it would do .Length + 1 to create the Byte array, adding a leading 0 because of that to the Modulus.
For Microsoft .net RSACryptoServiceProvider it would look like this


RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(3072); //Create 3072 Bit Key
byte[] sshrsa_bytes = Encoding.Default.GetBytes("ssh-rsa");
byte[] n = RSA.ExportParameters(false).Modulus;
byte[] e = RSA.ExportParameters(false).Exponent;
string buffer64;
using (MemoryStream ms = new MemoryStream())
{
ms.Write(ToBytes(sshrsa_bytes.Length), 0, 4);
ms.Write(sshrsa_bytes, 0, sshrsa_bytes.Length);
ms.Write(ToBytes(e.Length), 0, 4);
ms.Write(e, 0, e.Length);
ms.Write(ToBytes(n.Length+1), 0, 4); //Remove the +1 if not Emulating Putty Gen
ms.Write(new byte[] { 0 }, 0, 1); //Add a 0 to Emulate PuttyGen
ms.Write(n, 0, n.Length);
ms.Flush();
buffer64 = Convert.ToBase64String(ms.ToArray());
}
string pubssh = string.Format("ssh-rsa {0} generated-key", buffer64);

 

Testing the Program:

Program output if…
NO leading 0 added

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgKrIstbg1eQO3VKvHOcDEnx1gGX/8Jn7foWHv2uWbFqlL7AGZQNTz2VWiWntmgCNgg1pTnNKqOGTPpFDDHyqU0kfjL+cv8+j4Dlxr1axLs7KgzSZrW50XrXse3LEhfG1GgO9KwRu8Xt2Gb7X1aABm+bnaZQyxqxwJo9z5a4dTFbMiEQdl6ojBucINY/59j6J9/EuCCuEKV4Dr9IklgRuiIQEjzrzc8Tck32N+FMK/r16FIAwBUbC3szB+3IhDw1D8xS+JVngWUQzvujqPgbDEjJgoIkbcEnlqNO5d+g+BsIhreeVMscWPpDjfme8L3geX93UzNNrbJmpezmErcwMXDYdonVo/JhpE1WRVZswWbl4hCCvx6MFO5GkpEAy7G/jUqSDyk2wWI5Ayg4B58pgphOvzntQBmd+n3LGdKzG2DYH+mRBkFcnEnspHtjWIT64Q/dZmDRjQW1syYICR9Upo9Ynt0c5yNWHjGg+TufBr5xRbiWzlS9NJuRHTA0yXopTdQ== generated-key

WITH a leading 0 added

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqyLLW4NXkDt1SrxznAxJ8dYBl//CZ+36Fh79rlmxapS+wBmUDU89lVolp7ZoAjYINaU5zSqjhkz6RQwx8qlNJH4y/nL/Po+A5ca9WsS7OyoM0ma1udF617HtyxIXxtRoDvSsEbvF7dhm+19WgAZvm52mUMsascCaPc+WuHUxWzIhEHZeqIwbnCDWP+fY+iffxLggrhCleA6/SJJYEboiEBI8683PE3JN9jfhTCv69ehSAMAVGwt7MwftyIQ8NQ/MUviVZ4FlEM77o6j4GwxIyYKCJG3BJ5ajTuXfoPgbCIa3nlTLHFj6Q435nvC94Hl/d1MzTa2yZqXs5hK3MDFw2HaJ1aPyYaRNVkVWbMFm5eIQgr8ejBTuRpKRAMuxv41Kkg8pNsFiOQMoOAefKYKYTr857UAZnfp9yxnSsxtg2B/pkQZBXJxJ7KR7Y1iE+uEP3WZg0Y0FtbMmCAkfVKaPWJ7dHOcjVh4xoPk7nwa+cUW4ls5UvTSbkR0wNMl6KU3U= generated-key

Putty Gen Output (Matches the leading 0 added code)

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCqyLLW4NXkDt1SrxznAxJ8dYBl//CZ+36Fh79rlmxapS+wBmUDU89lVolp7ZoAjYINaU5zSqjhkz6RQwx8qlNJH4y/nL/Po+A5ca9WsS7OyoM0ma1udF617HtyxIXxtRoDvSsEbvF7dhm+19WgAZvm52mUMsascCaPc+WuHUxWzIhEHZeqIwbnCDWP+fY+iffxLggrhCleA6/SJJYEboiEBI8683PE3JN9jfhTCv69ehSAMAVGwt7MwftyIQ8NQ/MUviVZ4FlEM77o6j4GwxIyYKCJG3BJ5ajTuXfoPgbCIa3nlTLHFj6Q435nvC94Hl/d1MzTa2yZqXs5hK3MDFw2HaJ1aPyYaRNVkVWbMFm5eIQgr8ejBTuRpKRAMuxv41Kkg8pNsFiOQMoOAefKYKYTr857UAZnfp9yxnSsxtg2B/pkQZBXJxJ7KR7Y1iE+uEP3WZg0Y0FtbMmCAkfVKaPWJ7dHOcjVh4xoPk7nwa+cUW4ls5UvTSbkR0wNMl6KU3U= imported-openssh-key

 

 

Source Post on StackOverflow (For BouncyCastle) : https://stackoverflow.com/questions/15457710/converting-an-rsa-public-key-into-a-rfc-4716-public-key-with-bouncy-castle 

 

RSA Private Key Used in Testing.. (Do not use anywhere else of course it’s useless)

—–BEGIN RSA PRIVATE KEY—–
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
—–END RSA PRIVATE KEY—–