Hero

Como encriptar datos con el algoritmo Rijndael en .NET

Julio 18, 2013

aisen
C#
Microsoft
.Net
Programación

En esta entrada de blog veremos como encriptar datos en .NET con el algoritmo de criptografía Rijndael.

Rijndael es un algoritmo simétrico, comúnmente se le conoce como Advanced Encryption Standard (AES).

El ejemplo está desarrollado en ASP.NET pero se puede utilizar en distintos tipos de proyectos que podemos crear con .NET

Primero crearemos la clase Rijndael

1. Creamos la clase Rijndael

Esta clase tendrá los siguientes métodos:

  1. Encode
  2. Decode
  3. EncryptObjectToBytes
  4. DecryptObjectFromBytes**

1.1 Encode

A continuación presento el metodo usando para encriptar un objeto. Este método manda a encriptar el objeto, hace una llamada al método EncryptObjectToBytes que es el quien realiza la encriptación del mismo. El método retorna un string con el objeto encriptado y las claves para su decodificación, separados por el carácter “/”.

        /// <summary>
        /// Manda a encriptar un objecto
        /// </summary>
        /// <param name="pObject">Objecto a encriptar</param>
        /// <returns>Retorna el Objecto Encriptado con las Claves</returns>
        public static object Encode(object pObject)
        {
            //Creamos el algoritmo
            System.Security.Cryptography.Rijndael rijndael = System.Security.Cryptography.Rijndael.Create();

            //Almacenamos las claves
            object vlKey = rijndael.Key;
            object vlIV = rijndael.IV;

            //Usamos el algoritmo
            using (rijndael)
            {
                //Encriptamos el objecto
                object vlEncrypted = EncryptObjectToBytes(pObject, rijndael.Key, rijndael.IV);

                //Almacenamos en un string[] el objecto encritado
                string[] vlEnEncrypted = ((IEnumerable)vlEncrypted).Cast<object>()
                    .Select(x => x.ToString())
                    .ToArray();

                //Almacenamos en un string[] la clave 1
                string[] vlEnKey = ((IEnumerable)vlKey).Cast<object>()
                    .Select(x => x.ToString())
                    .ToArray();

                //Almacenamos en un string[] la clave 2
                string[] vlEnIV = ((IEnumerable)vlIV).Cast<object>()
                    .Select(x => x.ToString())
                    .ToArray();

                //Creamos el string con los datos encriptados
                string vlValueEncode = string.Empty;
                vlValueEncode = vlValueEncode  + string.Join(",", vlEnEncrypted);
                vlValueEncode = vlValueEncode + "/" + string.Join(",", vlEnKey);
                vlValueEncode = vlValueEncode + "/" + string.Join(",", vlEnIV);

                //Almacenamos en un objecto el string 
                object vlValueFinal = vlValueEncode;

                //Retornamos el objecto
                return vlValueFinal;
            }
        }

1.2 Decode

El método Decode llama al método DecryptObjectFromBytes, y le pasa por parámetros el objeto encriptado y las claves para su decodificación.

        /// <summary>
        /// Manda a desencriptar un objecto
        /// </summary>
        /// <param name="pEncode">Objecto Encriptado</param>
        /// <param name="pKey">Clave 1 Encriptada</param>
        /// <param name="pIV">Clave 2 Encriptada</param>
        /// <returns>Retorna el Objecto Desencriptado</returns>
        public static object Decode(byte[] pEncode, byte[] pKey, byte[] pIV)
        {
            //Mandamos a desencriptar el objecto
            object vlValue = DecryptObjectFromBytes(pEncode, pKey, pIV);

            //Si el objecto no es nulo
            if (vlValue != null)
            {
                //Retornamos el objecto
                return vlValue;
            }
            return null;
        }

1.3 Proceso de encryptación a bytes

Este método es el que utiliza el algoritmo Rijndael, recibe un objeto y retorna su valor codificado.

        /// <summary>
        /// Encriptamos el objecto
        /// </summary>
        /// <param name="pObject">Objecto a Encriptar</param>
        /// <param name="pKey">Clave 1</param>
        /// <param name="pIV">Clave 2</param>
        /// <returns>Retorna el objecto Encriptado</returns>
        private static byte[] EncryptObjectToBytes(object pObject, byte[] pKey, byte[] pIV)
        {
            //Verifica si los parametros son nulo
            if (pObject == null)
            {
                throw new ArgumentNullException();
            }
            if (pKey == null || pKey.Length <= 0)
            {
                throw new ArgumentNullException();
            }
            if (pIV == null || pIV.Length <= 0)
            {
                throw new ArgumentNullException();
            }

            //Creamos la variable byte[] que almacena el objecto encriptado
            byte[] encrypted;

            //Creamos el algoritmo
            System.Security.Cryptography.Rijndael rijndael = System.Security.Cryptography.Rijndael.Create();

            //Usamos el algoritmo
            using (rijndael)
            {
                //Le pasamos los valores de las claves al algoritmno
                rijndael.Key = pKey;
                rijndael.IV = pIV;

                //Creamos el Encriptador
                System.Security.Cryptography.ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, rijndael.IV);

                //Se crean las corrientes para el cifrado
                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (System.Security.Cryptography.CryptoStream csEncrypt = new System.Security.Cryptography.CryptoStream(msEncrypt, encryptor, System.Security.Cryptography.CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            //Escribe los datos en la secuencia
                            swEncrypt.Write(pObject);
                        }

                        //Almacenamos la encriptacion en el objecto
                        encrypted = msEncrypt.ToArray();
                    }
                }
            }

            //Retornamos el objecto encriptado
            return encrypted;
        }

1.4 DecryptObjectFromBytes

Este método recibe los parámetros que le pasa el método Decode (objeto encriptado, y sus claves) para luego descodificar el objeto, retorna el valor del objeto.

        /// <summary>
        /// Desencripta un objecto
        /// </summary>
        /// <param name="pObject">Objecto Encriptado</param>
        /// <param name="pKey">Clave 1</param>
        /// <param name="pIV">Clave 2</param>
        /// <returns>Retorna el Objecto Desencriptado</returns>
        private static object DecryptObjectFromBytes(byte[] pObject, byte[] pKey, byte[] pIV)
        {
            //Verifica si los parametros son nulo
            if (pObject == null || pObject.Length <= 0)
            {
                throw new ArgumentNullException();
            }
            if (pKey == null || pKey.Length <= 0)
            {
                throw new ArgumentNullException();
            }
            if (pIV == null || pIV.Length <= 0)
            {
                throw new ArgumentNullException();
            }

            //Variable que almacenara el valor del objecto encritado
            object vlDecodeObject = null;

            //Creamos el algoritmo
            System.Security.Cryptography.Rijndael rijndael = System.Security.Cryptography.Rijndael.Create();

            //Usamos el algoritmo
            using (rijndael)
            {
                //Le pasamos los valores de las claves al algoritmno
                rijndael.Key = pKey;
                rijndael.IV = pIV;

                //Creamos el Desencriptador
                System.Security.Cryptography.ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.IV);

                //Se crean las corrientes para el cifrado
                using (MemoryStream msDecrypt = new MemoryStream(pObject))
                {
                    using (System.Security.Cryptography.CryptoStream csDecrypt = new System.Security.Cryptography.CryptoStream(msDecrypt, decryptor, System.Security.Cryptography.CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                            //Escribe los datos en la secuencia, como un objecto (string) 
                            vlDecodeObject = srDecrypt.ReadToEnd();
                        }
                    }
                }

            }

            //Retornamos el objecto desencriptado
            return vlDecodeObject;
        }

2. Creamos la pagina ASP

Vamos a crear un webform, en donde colocaremos un textbox para el ingreso del texto, dos botones para encriptar y desencriptar.

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Rijndael.Default" %>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Algoritmo Rijndael</title>
</head>
<body>
    <link rel="stylesheet" href="Styles/css.css" />
    <form id="form1" runat="server">
    <div class="container_principal">
        <div class="container_info">
            <br />
            <asp:Label ID="lblIntroTexto" runat="server"  Text="Introduzca el texto a encriptar"/>
            <asp:TextBox ID="txtTexto" runat="server" />
            <br />
            <br />
            <asp:Button ID="btnEncriptar" runat="server" Text="Encriptar" OnClick="btnEncriptar_Click"/>
            <asp:Button ID="btnDesencriptar" runat="server" Text="Desencriptar" OnClick="btnDesencriptar_Click" />
            <br />
            <asp:Button ID="btnLimpiar" runat="server" Text="Limpiar" OnClick="btnLimpiar_Click"/>
        </div>
        <div class="container_result">
            <br />
            <asp:Label ID="lblInfoTextoEncritado" runat="server"  Text="Este es el texto encriptado:"/>
            <br />
            <asp:Label ID="lblTextoEncritado" runat="server" ForeColor="Red"/>
            <br />
            <br />
            <asp:Label ID="lblInfoTextoDesencriptado" runat="server" Text="Este es el texto desencriptado:" />
             <br />
            <asp:Label ID="lblTextoDesencriptado" runat="server" ForeColor="Red"/>
        </div>       
    </div>
    </form>
</body>
</html>

3. Encriptar el objecto

En el evento clic del botón encriptar llamamos al método Encode, como este retorna un string con el objeto encriptado y sus claves para la decodificación, debemos de sacar de ese string el valor encriptado y lo asignaremos al label lblTextoEncritado.

        protected void btnEncriptar_Click(object sender, EventArgs e)
        {
            //Texto a encriptar
            vlTexto = this.txtTexto.Text;
            
            //Mandamos a encriptar el texto, nos retorna el la encriptacion junto con las claves
            vlEncriptado = RijndaelEncrypt.Encode(vlTexto).ToString();

            string[] vlEnEncrypt = vlEncriptado.Split('/');

            string[] vlEncode = vlEnEncrypt[0].Split(',');

            foreach (string value in vlEncode)
            {
                vlTextoEncriptado = vlTextoEncriptado + value;
            }

            this.lblTextoEncritado.Text = vlTextoEncriptado;
 
         }

4. Desencriptamos el objecto.

En el evento clic del botón desencriptar llamamos al método Decode, y le pasamos los parámetros (objeto codificado, y sus claves). Como este método recibe datos de tipo byte arreglo tenemos que separar el string que nos devolvió el método Encode y colocarlo en arreglo de string, luego de esto tenemos que convertir los ítems del arreglo en bytes para poder enviárselo correctamente al método Decode. Este nos retorna el valor del objeto descodificado.

        protected void btnDesencriptar_Click(object sender, EventArgs e)
        {
            //Dividimos el valor encriptado en un string[]
            string[] vlEnEncrypt = vlEncriptado.Split('/');

            string[] vlEncode = vlEnEncrypt[0].Split(',');
            string[] vlKey = vlEnEncrypt[1].Split(',');
            string[] vlIV = vlEnEncrypt[2].Split(',');

            //Creamos las variables byte[] y le creamos el tamaño 
            byte[] vlByEncode = new byte[vlEncode.Length];
            byte[] vlByKey = new byte[vlKey.Length];
            byte[] vlByIV = new byte[vlIV.Length];

            //Variable int que almacena la cantidad de item del array
            int vlConEncode = vlEncode.Length - 1;
            //Recorremos el string[] y le pasamos el valor al byte[]
            for (int i = 0; i <= vlConEncode; i++)
            {
                vlByEncode[i] = byte.Parse(vlEncode[i]);
            }

            //Variable int que almacena la cantidad de item del array
            int vlConKey = vlKey.Length - 1;
            //Recorremos el string[] y le pasamos el valor al byte[]
            for (int i = 0; i <= vlConKey; i++)
            {
                vlByKey[i] = byte.Parse(vlKey[i]);
            }

            //Variable int que almacena la cantidad de item del array
            int vlConIV = vlEncode.Length - 1;
            //Recorremos el string[] y le pasamos el valor al byte[]
            for (int i = 0; i <= vlConIV; i++)
            {
                vlByIV[i] = byte.Parse(vlIV[i]);
            }

            //Mandamos a desencriptar el texto
            string vlValue = RijndaelEncrypt.Decode(vlByEncode, vlByKey, vlByIV).ToString();

            this.lblTextoDesencriptado.Text = vlValue;

        }

5. Visualización

encode

Con este algoritmo podemos encriptar nuestra información, si alguien accede a ella no le va a ser de utilidad ya que se encuentran encriptada.

Nosotros podemos ajustar la clase a nuestras necesidades, el ejemplo es como referencia para ver como podemos usar este algoritmo.

Adjunto el recurso del proyecto.

Espero les sea de ayuda.

Recibe consejos y oportunidades de trabajo 100% remotas y en dólares de weKnow Inc.