Pablo
Pablo

Reputation: 111

How to encrypt a byte array using own RSA encryption?

I'm trying to make my own RSA encryption. I know there are build in methods in C# but I wanted to make my own program because I want to understand how it's done. I think I'm messing up when converting from and to the byte array. If someone could push me in the right direction, that would be great :).

private void btnEncrypt_Click(object sender, EventArgs e)
{
    EncryptieModulo = 55;
    PublicKey = 27;
    var PlainText = Encoding.UTF8.GetBytes(txtPlaintext.Text);
    for (int i = 0; i < PlainText.Length; i++)
    {
        PlainText[i] = (byte)(BigInteger.Pow(PlainText[i], PublicKey) % EncryptieModulo);
    }

    textBox1.Text = Convert.ToBase64String(PlainText);
}

private void btnDecrypt_Click(object sender, EventArgs e)
{
    EncryptieModulo = 55;
    PrivateKey = 3;
    var CrypText = Convert.FromBase64String(txtCCryptedText.Text);
    for (int i = 0; i < CrypText.Length; i++)
    {
        CrypText[i] = (byte)(BigInteger.Pow(CrypText[i], PrivateKey) % EncryptieModulo);
    }

    textBox1.Text = Encoding.UTF8.GetString(CrypText);
}

Upvotes: 1

Views: 1959

Answers (1)

Andrew Savinykh
Andrew Savinykh

Reputation: 26280

Values that you encode have to be less than Modulo, which is in your case 55. In order for your example to work, you need to substitute Encoding.UTF8.GetBytes/Encoding.UTF8.GetString with your custom functions that translate latin alphabet characters to bytes between 0-54 and back.

For example you can do it like this:

private static byte[] GetBytes(string s)
{
    byte[] result = new byte[s.Length];
    for (int i = 0; i < s.Length; i++)
    {
        if (s[i] >= 'a' && s[i] <= 'z')
        {
            result[i] = (byte)(s[i] - 'a');
            continue;
        }
        if (s[i] >= 'A' && s[i] <= 'Z')
        {
            result[i] = (byte)(s[i] - 'A' + 26);
            continue;
        }
        throw new ArgumentOutOfRangeException();
    }
    return result;
}

private static string GetString(byte[] b)
{
    StringBuilder sb = new StringBuilder(b.Length);
    for (int i = 0; i < b.Length; i++)
    {
        if (b[i] >= 0 && b[i] < 26)
        {
            sb.Append((char)('a' + b[i]));
            continue;
        }
        if (b[i] >= 26 && b[i] < 52)
        {
            sb.Append((char)('A' + b[i] - 26));
            continue;
        }
        throw new ArgumentOutOfRangeException();
    }
    return sb.ToString();
}

Now substitute your Encoding.UTF8.GetBytes/Encoding.UTF8.GetString with our new ones and you should be good to go.

Note though, that what you just did is NOT really RSA encryption. You just have encrypted each byte individually using very short key. Security of this implementation is zilch. Please refer to the spec for all the intricacies of "real" implementation. (Padding for one comes to mind). In addition I advise you looking up a number of open source implementations of the real thing, if you want to understand the algorithm better.

Upvotes: 1

Related Questions