miércoles, 19 de enero de 2011

Implementación de Encripción de Cadenas y Archivos con AES256 ( algoritmo Rijndael)

En desarrollo es muy socorrido el uso de algoritmos de encripción de llave publica o privada, en este caso expongo una clase que implementa el algoritmo Rijndael o AES de 256bits, el cual es de llave privada, simétrico y de encripción por bloques. Para mas detalles ver http://es.wikipedia.org/wiki/Advanced_Encryption_Standard.

Esta clase es capaz de encriptar archivos pequeños (en un solo chunk) o grandes (usando múltiples chunks), así como cadenas de texto. Con algunos ligeros ajustes seria posible también encriptar o decriptar Streams.

En seguida el listado de código






using System;

using System.Collections;
using System.Text;
using System.Net;
using System.Security.Cryptography;

namespace F.Security.Cryptography
{
    public class AES256
    {

        #region Constants
        /// <summary>
        ///
        /// </summary>
        public const int AES256_BYTES = 32;
        /// <summary>
        ///
        /// </summary>
        public const int AES256_BITS = AES256_BYTES * 8;
        /// <summary>
        ///
        /// </summary>



        #endregion

        #region Private Members
        private int BUFFER_SIZE = 512;
        /// <summary>
        ///
        /// </summary>
        private string key = @"976ñqÉÞïg!@1XJ_bvs533ä_ƒy¼ŠÂùZBb坲i_ø_ã˘u6ù§‡NÀ_(#Ub•*xZp’¾§";


       private string passkey = @"f1búN&_š~4roZjáL^_,iMØŐ’v/=\89034R~îâDŽãþã®fà_ˆºDÛa¿z¾£qwy+[;]y";

        #endregion

        #region Public Property
        public int ChunkSize
        {
            set { BUFFER_SIZE = value; }
            get { return BUFFER_SIZE; }
        }
        public string PassKey
        {
            get
            {
                return passkey;
            }
        }
        #endregion

        #region Constructors
        public AES256()
        {

        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="key"></param>
        public AES256(string key)
        {
            SetPrivateKey(key);
        }

        #endregion

        #region Shared Crypting Methods
        /// <summary>
        ///
        /// </summary>
        /// <param name="strEncrypt"></param>
        /// <param name="strPK"></param>
        /// <returns></returns>
        public static byte[] Encrypt(string strEncrypt, string strPK)
        {
            Rijndael miRijndael = Rijndael.Create();
            byte[] encrypted = null;
            byte[] returnValue = null;

            try
            {
                miRijndael.Key = (new PasswordDeriveBytes(strPK, null)).GetBytes(AES256_BYTES);
                miRijndael.GenerateIV();

                byte[] toEncrypt = System.Text.Encoding.UTF8.GetBytes(strEncrypt);
                encrypted = (miRijndael.CreateEncryptor()).TransformFinalBlock(toEncrypt, 0, toEncrypt.Length);

                returnValue = new byte[miRijndael.IV.Length + encrypted.Length];
                miRijndael.IV.CopyTo(returnValue, 0);
                encrypted.CopyTo(returnValue, miRijndael.IV.Length);

            }
            catch { }
            finally { miRijndael.Clear(); }

            return returnValue;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="toEncrypt"></param>
        /// <param name="strPK"></param>
        /// <returns></returns>
        public static byte[] Encrypt(byte[] toEncrypt, string strPK)
        {
            Rijndael miRijndael = Rijndael.Create();
            byte[] encrypted = null;
            byte[] returnValue = null;

            try
            {
                miRijndael.Key = (new PasswordDeriveBytes(strPK, null)).GetBytes(AES256_BYTES);
                miRijndael.GenerateIV();

                encrypted = (miRijndael.CreateEncryptor()).TransformFinalBlock(toEncrypt, 0, toEncrypt.Length);

                returnValue = new byte[miRijndael.IV.Length + encrypted.Length];
                miRijndael.IV.CopyTo(returnValue, 0);
                encrypted.CopyTo(returnValue, miRijndael.IV.Length);

            }
            catch { }
            finally { miRijndael.Clear(); }

            return returnValue;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="bytDecrypt"></param>
        /// <param name="strPK"></param>
        /// <returns></returns>
        public static byte[] Decrypt(byte[] bytDecrypt, string strPK)
        {
            Rijndael miRijndael = Rijndael.Create();
            byte[] tempArray = new byte[miRijndael.IV.Length];
            byte[] encrypted = new byte[bytDecrypt.Length - miRijndael.IV.Length];
            byte[] returnValue = null;

            try
            {
                miRijndael.Key = (new PasswordDeriveBytes(strPK, null)).GetBytes(AES256_BYTES); ;

                Array.Copy(bytDecrypt, tempArray, tempArray.Length);
                Array.Copy(bytDecrypt, tempArray.Length, encrypted, 0, encrypted.Length);
                miRijndael.IV = tempArray;

                returnValue = (miRijndael.CreateDecryptor()).TransformFinalBlock(encrypted, 0, encrypted.Length);

            }
            catch { }
            finally { miRijndael.Clear(); }

            return returnValue;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="strDecrypt"></param>
        /// <param name="strPK"></param>
        /// <returns></returns>
        public static byte[] Decrypt(string strDecrypt, string strPK)
        {
            Rijndael miRijndael = Rijndael.Create();
            byte[] bytDecrypt = Convert.FromBase64String(strDecrypt);
            byte[] tempArray = new byte[miRijndael.IV.Length];
            byte[] encrypted = new byte[bytDecrypt.Length - miRijndael.IV.Length];
            byte[] returnValue = null;

            try
            {
                miRijndael.Key = (new PasswordDeriveBytes(strPK, null)).GetBytes(AES256_BYTES); ;

                Array.Copy(bytDecrypt, tempArray, tempArray.Length);
                Array.Copy(bytDecrypt, tempArray.Length, encrypted, 0, encrypted.Length);
                miRijndael.IV = tempArray;

                returnValue = (miRijndael.CreateDecryptor()).TransformFinalBlock(encrypted, 0, encrypted.Length);

            }
            catch { }
            finally { miRijndael.Clear(); }

            return returnValue;
        }
        #endregion

        #region Intance Crypting Methods
        /// <summary>
        ///
        /// </summary>
        /// <param name="PK"></param>
        public void SetPrivateKey(string PK)
        {
            key = PK;
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="bits"></param>
        /// <returns></returns>
        public static string GetStringKey(int bytes)
        {
            byte[] s = new byte[bytes];
            RandomNumberGenerator.Create().GetBytes(s);
            return System.Text.Encoding.Default.GetString(s);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="bits"></param>
        /// <returns></returns>
        public static byte[] GetBytesKey(int bytes)
        {
            byte[] s = new byte[bytes];
            RandomNumberGenerator.Create().GetBytes(s);
            return s;

        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string ToBase64String(byte[] bytes)
        {
            return Convert.ToBase64String(bytes);
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string UTF8BytesToString(byte[] bytes)
        {
            return System.Text.UTF8Encoding.UTF8.GetString(bytes);
        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="sourcefile"></param>
        /// <param name="targetfile"></param>
        public bool CryptFileByChunking(string sourcefile, string targetfile)
        {
            bool retval = false;
            int buffersize = BUFFER_SIZE;
            int continuereading = 1;
            byte[] buffer = new byte[buffersize];
            byte[] cryptedbuffer = null;

            System.IO.FileStream readfile = new System.IO.FileStream(sourcefile, System.IO.FileMode.Open);
            System.IO.FileStream writefile = new System.IO.FileStream(targetfile + "Temp", System.IO.FileMode.Create);
            try
            {

                while (continuereading > 0)
                {
                    continuereading = readfile.Read(buffer, 0, buffersize);

                    if (continuereading > 0)
                    {
                        cryptedbuffer = Encrypt(buffer, key);
                        writefile.Write(cryptedbuffer, 0, cryptedbuffer.Length);

                        cryptedbuffer = null;
                        buffer = new byte[buffersize];

                    }
                }
                retval = true;

            }
            catch
            {
                retval = false;
            }
            finally
            {
                readfile.Close();
                writefile.Close();
                if (retval == true)
                {
                    System.IO.File.Copy(targetfile + "Temp", targetfile, true);
                    System.IO.File.Delete(targetfile + "Temp");
                }

            }
            return retval;

        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourcefile"></param>
        /// <param name="targetfile"></param>
        /// <returns></returns>
        public bool CryptFile(string sourcefile, string targetfile)
        {
            bool retval = false;

            byte[] buffer;
            byte[] cryptedbuffer = null;

            System.IO.FileStream readfile = System.IO.File.OpenRead(sourcefile);
            System.IO.FileStream writefile = new System.IO.FileStream(targetfile + "Temp", System.IO.FileMode.Create);
            try
            {

                buffer = new byte[readfile.Length];

                readfile.Read(buffer, 0, buffer.Length);

                cryptedbuffer = Encrypt(buffer, key);
                writefile.Write(cryptedbuffer, 0, cryptedbuffer.Length);

                cryptedbuffer = null;

                retval = true;

            }
            catch
            {
                retval = false;
            }
            finally
            {
                readfile.Close();
                writefile.Close();
                if (retval == true)
                {
                    System.IO.File.Copy(targetfile + "Temp", targetfile, true);
                    System.IO.File.Delete(targetfile + "Temp");
                }
            }
            return retval;

        }

        /// <summary>
        ///
        /// </summary>
        /// <param name="sourcefile"></param>
        /// <param name="targetfile"></param>
        public bool DecryptFileByChunking(string sourcefile, string targetfile)
        {
            bool retval = false;
            int continuereading = 1;
            int buffersize = BUFFER_SIZE + AES256_BYTES;
            byte[] buffer = new byte[buffersize];
            byte[] decryptedbuffer = null;
            System.IO.FileStream readfile = new System.IO.FileStream(sourcefile, System.IO.FileMode.Open);
            System.IO.FileStream writefile = new System.IO.FileStream(targetfile + "Temp", System.IO.FileMode.Create);

            try
            {

                while (continuereading > 0)
                {

                    continuereading = readfile.Read(buffer, 0, buffersize);

                    if (continuereading > 0)
                    {

                        decryptedbuffer = Decrypt(buffer, key);
                        writefile.Write(decryptedbuffer, 0, decryptedbuffer.Length);
                        decryptedbuffer = null;
                        buffer = new byte[buffersize];

                    }
                }
                retval = true;
            }
            catch
            {
                retval = false;
            }
            finally
            {
                readfile.Close();
                writefile.Close();
                if (retval == true)
                {
                    System.IO.File.Copy(targetfile + "Temp", targetfile, true);
                    System.IO.File.Delete(targetfile + "Temp");
                }
            }
            return retval;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="sourcefile"></param>
        /// <param name="targetfile"></param>
        /// <returns></returns>
        public bool DecryptFile(string sourcefile, string targetfile)
        {
            bool retval = false;

            byte[] buffer;
            byte[] decryptedbuffer = null;

            System.IO.FileStream readfile = System.IO.File.OpenRead(sourcefile);
            System.IO.FileStream writefile = new System.IO.FileStream(targetfile + "Temp", System.IO.FileMode.Create);

            try
            {

                buffer = new byte[readfile.Length];
                readfile.Read(buffer, 0, buffer.Length);
                decryptedbuffer = Decrypt(buffer, key);
                writefile.Write(decryptedbuffer, 0, decryptedbuffer.Length);
                decryptedbuffer = null;

                retval = true;
            }
            catch
            {
                retval = false;
            }
            finally
            {


                readfile.Close();
                writefile.Close();
                if (retval == true)
                {
                    System.IO.File.Copy(targetfile + "Temp", targetfile, true);
                    System.IO.File.Delete(targetfile + "Temp");
                }

            }
            return retval;
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="file1"></param>
        /// <param name="file2"></param>
        /// <param name="overwrite"></param>
        public static void BackupFile(string file1, string file2, bool overwrite)
        {
            System.IO.File.Copy(file1, file2, overwrite);
        }

        #endregion


    }
}


Transacciones Fiori

  /UI2/CACHE Register service for UI2 cache use /UI2/CACHE_DEL Delete cache entries /UI2/CHIP Chip Registration /UI2/CUST Customizing of UI ...