Julio 18, 2013
aisen
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:
- Encode
- Decode
- EncryptObjectToBytes
- 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
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.