Criptografía: Algoritmos Asimétricos
Continuando con el tema de criptografía, en esta ocasión vamos a escribir acerca de los algoritmos asimétricos.
¿De qué se trata? (o bien, WTF? como diría mi estimado Maic)
Los algoritmos asimétricos se encargan de encriptar datos, para realizarlo se apoyan del uso de una clave pública y una privada; este tipo de algoritmos han sido diseñados con el propósito de poder intercambiar información de manera segura sin necesidad de haber acordado previamente una clave secreta de cifrado.
Dentro de los algoritmos comúnmente más utilizados encontramos el algoritmo RSA, y el nombre lo toma por sus creadores Rivest, Shamir y Adleman, esto nos sirve como contexto histórico para la próxima que nos pregunten en clase sobre los inventores del RSA, jaja.
Donde de sus principales implementaciones, lo podemos encontrar en canales de comunicación segura, con el uso de SSL o TSL.
Para poder implementarlo, .NET ofrece los siguientes proveedores:
-
DSACryptoServiceProvider
-
RSACryptoServiceProvider
Una vez revisado un poco de teoría, vamos a realizar un ejemplo para conocer de qué manera podemos implementar los algoritmos asimétricos:
- Creamos un proyecto de aplicación Windows, con tres cajas de texto y dos botones principalmente.
- En nuestro código realizamos la importación del espacio de nombres System.Security.Cryptography.
VB
Imports System.Security.Cryptography
CS
using System.Security.Cryptography;
- En nuestra clase se define a nuestro proveedor del cifrado, que para nuestro ejemplo será una implementación del algoritmo RSA.
VB
Private alg As RSACryptoServiceProvider
CS
private RSACryptoServiceProvider alg;
- En el constructor de la clase se define la instancia del algoritmo
VB
Public Sub New()
InitializeComponent()
alg = New RSACryptoServiceProvider()
End Sub
CS
public Form1()
{
InitializeComponent();
alg = new RSACryptoServiceProvider();
}
Al trabajar con algoritmos asimétricos, se hizo referencia al uso de llaves y precisamente relacionado con esto, tenemos algunos métodos disponibles para hacer la creación de las llaves. Es por esta razón, que definimos el siguiente método, donde vamos a generar la información de las llaves y la haremos persistir en un archivo xml. Para realizar esto, utilizaremos algunas clases que son parte del espacio de nombres System.IO.
VB
Private Sub CrearLlave(ByVal archivo As String)
Dim llave As String = alg.ToXmlString(True)
Dim fs As New FileStream(archivo, FileMode.Create)
Dim sw As New StreamWriter(fs)
sw.Write(llave)
sw.Close()
End Sub
CS
private void CrearLlave(string archivo)
{
string llave = alg.ToXmlString(true);
FileStream fs = new FileStream(archivo, FileMode.Create);
StreamWriter sw = new StreamWriter(fs);
sw.Write(llave);
sw.Close();
}
En el código anterior podemos notar que se utiliza el método ToXmlString, el cual recibe un parámetro booleano, el cual estará afectando si el resultado incluye también la llave privada o exclusivamente contendrá la llave pública.
- Ahora creamos una función para encargarse de la encriptación de los datos, la cual a su vez llamará al método que realiza la creación de la llave.
VB
Private Function Encriptar(ByVal input As Byte()) As Byte()
CrearLlave("key.xml")
Dim output() As Byte = alg.Encrypt(input, True)
Return output
End Function
CS
private byte[] Encriptar(byte[] input)
{
CrearLlave("key.xml");
byte[] output= alg.Encrypt(input, false);
return output;
}
- Ya casi lo tenemos, solo falta realizar la llamada a nuestro método de encriptación y para esto, lo hacemos en el método que responde al clic de nuestro botón “Encriptar”.
VB
Private Sub btnEncriptar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEncriptar.Click
Dim textoOriginal() As Byte = System.Text.Encoding.UTF8.GetBytes(textValor.Text)
textResultado.Text = Convert.ToBase64String(Encriptar(textoOriginal))
End Sub
CS
private void btnEncriptar_Click(object sender, EventArgs e)
{
byte[] textoOriginal = System.Text.Encoding.UTF8.GetBytes(textValor.Text);
textResultado.Text= Convert.ToBase64String(Encriptar(textoOriginal));
}
- Ejecutamos nuestro ejemplo, ingresando como valor “Password” y observamos el resultado en la caja de texto correspondiente al valor cifrado.
- Listo! El resultado de la encriptación de los datos lo podemos ver en la caja de texto correspondiente al valor cifrado; y de paso también aprovechamos para revisar el contenido del documento XML generado que incluye información acerca de la llave generada.
- Primera parte completada! Los datos han sido encriptados, pero estamos a la mitad del proceso, puesto que ahora es importante poder descifrar esa información. Debido a esto vamos a definir el siguiente método que nos ayudara en el proceso de descifrar los datos:
VB
Private Function Desencriptar(ByVal input As Byte()) As Byte()
alg = CargarLlave("key.xml")
Dim output() As Byte = alg.Decrypt(input, True)
Return output
End Function
CS
private byte[] Desencriptar(byte[] input)
{
alg = CargarLlave("key.xml");
byte[] output = alg.Decrypt(input, false);
return output;
}
- En el clic del botón “Desencriptar” mandamos llamar el método previamente definido:
VB
Private Sub btnDesencriptar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDesencriptar.Click
Dim textoOriginal() As Byte = Convert.FromBase64String(textResultado.Text)
Try
textInicial.Text = System.Text.Encoding.UTF8.GetString(Desencriptar(textoOriginal))
Catch ex As Exception
MessageBox.Show("Lo siento, imposible descifrar los datos!")
End Try
End Sub
CS
private void btnDesencriptar_Click(object sender, EventArgs e)
{
try
{
byte[] textoOriginal = Convert.FromBase64String(textResultado.Text);
textInicial.Text = System.Text.Encoding.UTF8.GetString(Desencriptar(textoOriginal));
}
catch
{
MessageBox.Show("Lo siento, imposible descifrar los datos!");
}
}
- Ejecutamos nuestra aplicación y comprobamos que con el valor cifrado y con la llave previamente creada, el resultado esperado debe ser equivalente al valor original y efectivamente el resultado nos da el valor de “Password”.
- Para asegurarnos que los datos cifrados se interpretan únicamente con la llave creada, lo que haremos es alterar el contenido de la llave en nuestro documento xml y volvemos a ejecutar.
Comprobamos el resultado, el cual es Incorrecto, tal y como se esperaba. Y con ello confirmamos que exclusivamente los datos cifrados se van a interpretan con la llave con la cual han sido encriptados previamente.
Espero que esta nota sea de utilidad, el código en sus dos versiones lo pueden descargar aquí
Nos encontramos en la próxima.