lunedì 2 aprile 2012

System.Security.Cryptography.RSACryptoServiceProvider

 

Esempio per un semplice utilizzo di crittografia a chiave asimmetrica…

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

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;
    }
}

E relativo utilizzo…

public class UseEnryption {
   
    private string privatekey=string.Empty;
    private string publickey=string.Empty;
    private int keylength = 4096;

    string Crypt(string plaintext) {
        try
        {
            if (publickey == string.Empty)
            {
                GenerateKeys(keylength);
            }
            return AsymmetricEncryption.EncryptText(plaintext, keylength, publickey);
        }
        catch (Exception ex)
        {

            return ex.Message;
        }
  
    }
    
    string Decrypt(string encryptedtext) {
        try
        {
            if (privatekey == string.Empty)
            {
                GenerateKeys(keylength);
            }
            return AsymmetricEncryption.DecryptText(encryptedtext, keylength, privatekey);
        }
        catch (Exception ex)
        {

            return ex.Message;
        }
      
    }
    public void GenerateKeys(int keylength) {
        AsymmetricEncryption.GenerateKeys(keylength, out publickey, out privatekey);
    }

    }

P.S le chiavi vengono rigenerate ogni volta che si invoca il metodo GenerateKeys. Salvare le chiavi su un supporto fisico per mantenerle.

Spero vi sia utile.

Nessun commento: