How to

encrypt/decrypt using asymmetric algorithm RSA

Published: 7. February 2012 | Updated: 7. February 2012
License: Microsoft Public License (MS-PL)
Categories: Security » Encryption
Tags: C# Security
Was this snippet helpful for you? YESYES / NONO

Class for encrypting, decrypting bytes and text with public and private keys using asymmetric algorithm RSA. Also enables generate keys. RSA is used for encrypting smaller amount of data. Use GetMaxDataLength method to check maximum data length for specified key size.

Import namespaces

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

Class

public static class AsymmetricEncryption
{
    private static bool _optimalAsymmetricEncryptionPadding = false;

    public static void GenerateKeys(int keySize, out string publicKey, out string publicAndPrivateKey)
    {
        using (var provider = new RSACryptoServiceProvider(keySize))
        {
            publicKey = provider.ToXmlString(false);
            publicAndPrivateKey = provider.ToXmlString(true);
        }
    }

    public static string EncryptText(string text, int keySize, string publicKeyXml)
    {
        var encrypted = Encrypt(Encoding.UTF8.GetBytes(text), keySize, publicKeyXml);
        return Convert.ToBase64String(encrypted);
    }

    public static byte[] Encrypt(byte[] data, int keySize, string publicKeyXml)
    {
        if (data == null || data.Length == 0) throw new ArgumentException("Data are empty", "data");
        int maxLength = GetMaxDataLength(keySize);
        if (data.Length > maxLength) throw new ArgumentException(String.Format("Maximum data length is {0}", maxLength), "data");
        if (!IsKeySizeValid(keySize)) throw new ArgumentException("Key size is not valid", "keySize");
        if (String.IsNullOrEmpty(publicKeyXml)) throw new ArgumentException("Key is null or empty", "publicKeyXml");

        using (var provider = new RSACryptoServiceProvider(keySize))
        {
            provider.FromXmlString(publicKeyXml);
            return provider.Encrypt(data, _optimalAsymmetricEncryptionPadding);
        }
    }

    public static string DecryptText(string text, int keySize, string publicAndPrivateKeyXml)
    {
        var decrypted = Decrypt(Convert.FromBase64String(text), keySize, publicAndPrivateKeyXml);
        return Encoding.UTF8.GetString(decrypted);
    }

    public static byte[] Decrypt(byte[] data, int keySize, string publicAndPrivateKeyXml)
    {
        if (data == null || data.Length == 0) throw new ArgumentException("Data are empty", "data");
        if (!IsKeySizeValid(keySize)) throw new ArgumentException("Key size is not valid", "keySize");
        if (String.IsNullOrEmpty(publicAndPrivateKeyXml)) throw new ArgumentException("Key is null or empty", "publicAndPrivateKeyXml");

        using (var provider = new RSACryptoServiceProvider(keySize))
        {
            provider.FromXmlString(publicAndPrivateKeyXml);
            return provider.Decrypt(data, _optimalAsymmetricEncryptionPadding);
        }
    }

    public static int GetMaxDataLength(int keySize)
    {
        if (_optimalAsymmetricEncryptionPadding)
        {
            return ((keySize - 384) / 8) + 7;
        }
        return ((keySize - 384) / 8) + 37;
    }

    public static bool IsKeySizeValid(int keySize)
    {
        return keySize >= 384 &&
                keySize <= 16384 &&
                keySize % 8 == 0;
    }
}

Use

const int keySize = 1024;
string publicAndPrivateKey;
string publicKey;

AsymmetricEncryption.GenerateKeys(keySize, out publicKey, out publicAndPrivateKey);

string text = "text for encryption";
string encrypted = AsymmetricEncryption.EncryptText(text, keySize, publicKey);
string decrypted = AsymmetricEncryption.DecryptText(encrypted, keySize, publicAndPrivateKey);
Console.WriteLine("Encrypted: {0}", encrypted);
Console.WriteLine("Decrypted: {0}", decrypted);
Console Output:
Encrypted: viBc7Z4fK0jZjwUzeDRApsoKxjr/gv0N0pZnQAb2IECDVaU4vYazjEpcPkrJZ7U97myxf
NKOBEsem6v6UMQDGEHOoGBZwnAPgjG8/edLchiLtKGZ0B/DIl6KXEmnAbzPnB6Ou0femHSK9Ms33OX0g
ZBDvS7nSy+uBPzjds/S+9Y=
Decrypted: text for encryption
Send us feedback about this snippet »



Related Snippets: