CommunistPancake
CommunistPancake

Reputation: 605

Get the public key from RSACryptoServiceProvider?

I'm trying to use public key encryption for communication with a client and server. The server is supposed to generate a 1024-bit public key and send it to the client, where the client will use that key to send encrypted data back to the server. So far, I've initialized the RSACryptoServiceProvider with this:

RSACryptoServiceProvider rsaEncryption = new RSACryptoServiceProvider(1024);

Now, I'm aware that I can use ExportParameters to get the exponent and modulus from the RSACryptoServiceProvider. However, I'm wondering, how can I use this data to send a public key back to the client (which would also be using an RSACryptoServiceProvider), and how can the client use this data to encrypt something to send back to me? Or am I doing this completely wrong?

Upvotes: 8

Views: 22659

Answers (2)

Cam Moten
Cam Moten

Reputation: 119

1 - Please use >= 2048 Bits in your key to be protected til ~2025.

The above is from 2012, but I came across it while trying to create a ssh-rsa key for Putty / Linux server connections.

I've just solved similar problem of creating a public ssh-rsa key in the proper format, to match PuttyGen.

For Microsoft .net RSACryptoServiceProvider it would look like this

            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(3072);
            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 (remove it not emulating)
                ms.Write(n, 0, n.Length);
                ms.Flush();
                buffer64 = Convert.ToBase64String(ms.ToArray());
            }

            string pubssh = string.Format("ssh-rsa {0} generated-key", buffer64);

You can see my Private Key I used for testing & the putty gen source code link https://www.cameronmoten.com/2017/12/21/rsacryptoserviceprovider-create-a-ssh-rsa-public-key/

I work at Microsoft but this is a personal answer not a Microsoft one.

Original Post for BouncyCastle (Link)

Upvotes: 2

Mehmet Ataş
Mehmet Ataş

Reputation: 11549

Your logic seems ok and it seems that you only need some sample code.

    using System;
    using System.Security.Cryptography;
    using System.Text;

    namespace RSA
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    var rsaServer = new RSACryptoServiceProvider(1024);
                    var publicKeyXml = rsaServer.ToXmlString(false);

                    var rsaClient = new RSACryptoServiceProvider(1024);
                    rsaClient.FromXmlString(publicKeyXml);

                    var data = Encoding.UTF8.GetBytes("Data To Be Encrypted");

                    var encryptedData = rsaClient.Encrypt(data, false);
                    var decryptedData = rsaServer.Decrypt(encryptedData, false);

                    Console.WriteLine(Encoding.UTF8.GetString(decryptedData));

                    Console.WriteLine("OK");
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                Console.Read();
            }
        }
    }

Upvotes: 25

Related Questions