0

I'm trying to use the System.Security.Cryptography.RSA class in C#. I want to my C# script to send the rsa public key to my server after it created one. I wrote the server in python, so I need the public key as a number, but honestly I have no idea how to do that. My code:

RSA rsaObj = RSA.Create();
RSAParameters rsaParas = rsaObj.ExportParameters(false);
byte[] eByte = rsaParas.Exponent;
byte[] nByte = rsaParas.Modulus;

So now I have e (public key exponent) and N (modulus) as bytes. I can convert them to a Base64String with:

String eB64 = Convert.ToBase64String(eByte);
String nB64 = Convert.ToBase64String(nByte);

Now I have strings like that:

wGFd7jRNC09H/TvgcYU5BduqKtAkRQHoHw6lNakfcGAu8Y/qKg+s6jmlq8N9UWqgSKK87Rrfw8pf9ne9wqxVpSO8LHW0WS9/V2IxcX0fzVJPe+L1HhT5cXGrFHMWOyYKkZB+NaIJUIlZUY5JWyX6SdPwt8QBcHpuY/jXSMg8rqU=

I don't know how get the real numbers out if that. It looks like I'm the only one with this problem, because I couldn't find anything about this.

Jan Gimmler
  • 43
  • 1
  • 8

1 Answers1

0

I'm not sure I understand exactly what you want but you may find this useful.

        var eByteString = eByte.Aggregate(string.Empty, (current, n) => current + n.ToString("000"));
        var nByteString = nByte.Aggregate(string.Empty, (current, n) => current + n.ToString("000"));

or you can do it without extensions like:

        //convert to decimal string
        var eByteString = string.Empty;
        foreach (byte b in eByte)
            eByteString = eByteString + b.ToString("000");

        var nByteString = string.Empty;
        foreach (byte b in nByte)
            nByteString = nByteString + b.ToString("000");

the result would be something like:

eByteString : 001000001

nByteString : 211110203128097225245156190057058005219074254110126137008162017185117098093007197199208188134068102171169132057218155254193154082182076214158032164159255142114232250019158058134077184026065093207059162082149098217128015167051030117204095144063074166219072006156228075166154194003029165048078213089138010151145220240249163048191014154160090207050215127170028113070212074123108011170137

These two lines convert both eByte and nByte to decimal representation of the byte array (every 3 character represents a single byte to make converting the string to original byte array possible).

to convert it back to byte array in c# you can use provided extension method:

static class Extensions
{
    public static IEnumerable<String> SplitParts(this string text, int length)
    {
        for (var i = 0; i < text.Length; i += length)
            yield return text.Substring(i, Math.Min(length, text.Length - i));
    }
}

and conversion would be like:

        var arr = eByteString.SplitParts(3).Select(s => Convert.ToByte(s)).ToArray();

here is the complete sample for convering to decimal string and back to byte array:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;

namespace Test
{

    static class Extensions
    {
        public static IEnumerable<String> SplitParts(this string text, int length)
        {
            for (var i = 0; i < text.Length; i += length)
                yield return text.Substring(i, Math.Min(length, text.Length - i));
        }
    }

    static class Program
    {
        static void Main()
        {
            RSA rsaObj = RSA.Create();
            RSAParameters rsaParas = rsaObj.ExportParameters(false);
            byte[] eByte = rsaParas.Exponent;
            byte[] nByte = rsaParas.Modulus;

            //convert to decimal string
            var eByteString = eByte.Aggregate(string.Empty, (current, n) => current + n.ToString("000"));
            var nByteString = nByte.Aggregate(string.Empty, (current, n) => current + n.ToString("000"));

            //convert back to array
            var arrEByteString = eByteString.SplitParts(3).Select(s => Convert.ToByte(s)).ToArray();
            var arrNByteString = nByteString.SplitParts(3).Select(s => Convert.ToByte(s)).ToArray();
        }
    }
}
Community
  • 1
  • 1
user3473830
  • 7,165
  • 5
  • 36
  • 52
  • My compiler couldn't find the method "Aggregate". Do I have to import something? – Jan Gimmler Oct 15 '14 at 18:47
  • aggregate is an extension method, add `using System.Linq;` and you need .Net 3.5 or higher – user3473830 Oct 15 '14 at 18:49
  • Furthermore I don't know whether that's the right answer to my question. I need the variables N (private & public key modulus) and e (public key exponent). The bytes are the only thing I can get from the .NET RSA implementation. Do your this strings represent the values I can calculate with (encrypt my data)? – Jan Gimmler Oct 15 '14 at 18:56
  • There we got the problem: I am using Unity Engine which uses NET 2.0... Are there any alternatives? – Jan Gimmler Oct 15 '14 at 18:58
  • @JanGimmler, I updated the code for alternative method, and yes you can use it to decrypt/encrypt (one way since you just exported public key), you should call `ImportParameter` and add back the parameters to crypto provider, for more information have a look at http://stackoverflow.com/questions/17128038/c-sharp-rsa-encryption-decryption-with-transmission – user3473830 Oct 15 '14 at 19:09
  • @JanGimmler, btw please add unity-3d tag to your question. – user3473830 Oct 15 '14 at 19:10
  • 1
    This is much worse than the base64 encoding he started with. – President James K. Polk Oct 15 '14 at 23:09
  • I don't know why the answer get down voted,I never said this is an efficient or correct way to transfer the keys, but the answer is based on collaboration with @JanGimmler who asked the question. – user3473830 Oct 16 '14 at 09:15
  • The problem is that I don't know a more efficient way to transfer the key when just one side is using the .NET implementation. – Jan Gimmler Oct 17 '14 at 21:18