El blog del burgués

14 marzo 2010

Encriptación Asimétrica con C#.NET

Filed under: C# — elburgues @ 6:02 PM

La encriptación asimétrica a menudo recibe el nombre de encriptación de llave pública. Dos partes remotas son capaces de intercambiar información sensible de forma segura sin necesidad de compartir una única llave (como vimos en la encriptación simétrica). En este caso, cada parte tiene dos llaves (por eso se les llama algoritmos asimétricos):

  • Una pública (puede estar accesible para cualquiera), la cual se usa para encriptar.
  • Una privada (no puede conocerla nadie más), la cual se va a usar para desencriptar.

Consejo: Una regla criptográfica básica prohíbe la reutilización de claves, es decir, las dos claves deberían ser únicas en cada sesión de comunicación.

Funcionamiento:

  • Ana crea un par de claves, una de las cuales mantiene en secreto y la otra la envía a Jose.
  • Jose crea un par de claves, una de las cuales mantiene en secreto y la otra la envía a Ana.
  • Ana crea un mensaje y lo encripta con la clave pública que ha recibido de Jose.
  • Ana envía el mensaje encriptado a Jose.
  • Jose utiliza su clave privada para desencriptar el mensaje de Ana y poder leerlo.

El funcionamiento se basa en que el par de claves (pública/privada) generadas por cada una de las partes remotas, están vinculadas matemáticamente entre sí, de forma que, el mensaje que se haya encriptado con la clave pública, solamente puede ser descifrado con la llave privada. Una tercera parte no autorizada podría hacerse con la clave pública de cualquiera de las dos partes comunicantes, incluso, interceptar el mensaje cifrado. No obstante, el intruso no puede descifrar el mensaje con ninguna clave pública. El mensaje solo puede descifrarse con la clave privada de la parte que ha emitido el mensaje cifrado.

Hoy en día, el algoritmo de encriptación asimétrica más usado es RSA (.NET Framework es el único que soporta). La limitación principal de los algoritmos asimétricos es que son relativamente lentos, no son prácticos para la encriptación de grandes cantidades de datos. Los algoritmos asimétricos usan claves cuyas longitudes son mucho más largas que las claves de los algoritmos simétricos. La siguiente tabla es una comparativa de la resistencia de ambos tipos de claves frente a ataques por fuerza bruta, dependiendo de su longitud:

Longitudes de claves simétricas

Longitudes de claves asimétricas

64 bits.

512 bits.

80 bits.

768 bits.

112 bits.

1792 bits.

128 bits.

2304 bits.

Normalmente, el cifrado de clave pública se utiliza para cifrar la clave y el vector de inicialización que serán utilizados por un algoritmo simétrico. Después de transferir la clave y el vector de inicialización, el cifrado de clave secreta se utiliza para el resto de la sesión, pero eso es algo que veremos en otra entrada cuando hablemos de la encriptación híbrida.

Esquemas de relleno

Los algoritmos de encriptación asimétrica se apoyan en los esquemas de relleno para protegerse frente a ataques específicos de la misma manera que los algoritmos simétricos se apoyan en los modos de cifrado. Los esquemas de relleno también aseguran que la función encriptadora no tiene que procesar bloques parciales de datos. Los esquemas de relleno asimétrico son una serie de instrucciones que especifican como preparar los datos antes de la encriptación, y suelen mezclar el texto sin cifrar con otros datos para crear un texto cifrado que es mucho más largo que el mensaje original.

.NET Framework soporta dos esquemas de relleno para el algoritmo asimétrico RSA:

  • Optimal Asymmetric Encryption Padding (OAEP).
  • PKCS #1 v1.5.

OAEP es un esquema más nuevo que provee protección frente a ataques a los cuales el esquema PKCS #1 v1.5 es vulnerable. Debería de usarse siempre OAEP (el cual solo está disponible en windows XP, o también disponible en versiones anteriores de windows que hayan sido actualizadas con el paquete “high encryption”). No es necesario profundizar en los detalles de los esquemas de relleno, tan solo saber que se usan junto con el algoritmo asimétrico para lograr más protección de los datos confidenciales.

Programando encriptación asimétrica con C#.NET

Aquí dejo un ejemplo con los aspectos más fundamentales de manejo de RSA con C#.NET:


using System;
using System.Security.Cryptography;
using System.Text;
namespace Encription
{
   class RSA
   {
      [STAThread]
      static void Main()
      {
         // Definimos el texto a encriptar
         byte[] mensajeSinCifrar = Encoding.Default.GetBytes("Seguridad en .NET Framework");
         Console.WriteLine("Mensaje original:");
         Console.WriteLine("Seguridad en .NET Framework");
         Console.WriteLine("Pulse una tecla para continuar\n");
         Console.ReadKey();
         // Instanciamos el algorimo asimétrico RSA
         RSACryptoServiceProvider primerRSA = new RSACryptoServiceProvider();
         // Establecemos la longitud de la clave que queremos usar
         primerRSA.KeySize = 2048;
         // Encriptamos el mensaje con un relleno OAEP.
         byte[] mensajeCifrado = primerRSA.Encrypt(mensajeSinCifrar, true);
         Console.WriteLine("Mensaje encriptado:");
         Console.WriteLine(Encoding.Default.GetString(mensajeCifrado));
         Console.WriteLine("Pulse una tecla para continuar\n");
        Console.ReadKey();
         // Desencriptamos el mensaje
         byte[] mensajeDescifrado = primerRSA.Decrypt(mensajeCifrado, true);
         // Sacamos el mensaje descifrado por consola
         string mensajeOriginal = Encoding.Default.GetString(mensajeDescifrado);
         Console.WriteLine("Mensaje desencriptado:");
         Console.WriteLine(mensajeOriginal);
         Console.WriteLine("Pulse una tecla para finalizar\n");
         Console.ReadKey();
      }
   }
}
Anuncios

4 comentarios »

  1. Me parece muy buena la información que has publicado amigo, el código ejemplo es bastante claro; pero como puedo generar mis propias llaves publicas y privadas para cifrar y decifrar la información ?

    Comentario por Daniel J. Jacome — 26 agosto 2010 @ 7:27 PM | Responder

    • Usando la clase RSAParameters

      //initialze the byte arrays to the public key information.
      byte[] PublicKey = {214,46,220,83,160,73,40,39,201,155,19,202,3,11,191,178,56,
      74,90,36,248,103,18,144,170,163,145,87,54,61,34,220,222,
      207,137,149,173,14,92,120,206,222,158,28,40,24,30,16,175,
      108,128,35,230,118,40,121,113,125,216,130,11,24,90,48,194,
      240,105,44,76,34,57,249,228,125,80,38,9,136,29,117,207,139,
      168,181,85,137,126,10,126,242,120,247,121,8,100,12,201,171,
      38,226,193,180,190,117,177,87,143,242,213,11,44,180,113,93,
      106,99,179,68,175,211,164,116,64,148,226,254,172,147};

      byte[] Exponent = { 1, 0, 1 };

      //Create a new instance of RSACryptoServiceProvider.
      RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();

      //Create a new instance of RSAParameters.
      RSAParameters RSAKeyInfo = new RSAParameters();

      //Set RSAKeyInfo to the public key values.
      RSAKeyInfo.Modulus = PublicKey;
      RSAKeyInfo.Exponent = Exponent;

      //Import key parameters into RSA.
      RSA.ImportParameters(RSAKeyInfo);

      Comentario por elburgues — 27 agosto 2010 @ 4:13 PM | Responder

  2. Seria estupendo que se publicaran un articulo con el mismo formato de “Encriptacion Asimetrica” pero abarcando el tema de las llaves RSA. 🙂

    Comentario por Juarez — 19 marzo 2011 @ 4:59 PM | Responder

  3. Excelente explicacion muchas gracias

    Comentario por JPablo — 3 noviembre 2011 @ 1:00 AM | Responder


RSS feed for comments on this post.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

Crea un blog o un sitio web gratuitos con WordPress.com.

A %d blogueros les gusta esto: