domingo, 28 de septiembre de 2014

Pregunta C# (11 de 20): ¿Cómo Encriptar y Desencriptar una Cadena de Caracteres en .NET?

Índice

0. Introducción
1. Contexto
1.1 ¿Qué es la encriptación?
2. Encriptar y Desencriptar un Objeto String en .NET
2.1 Clase DESEncrypt
2.2 Clase de prueba PruebaEncriptacion
3. Recursos
4. Conclusiones
5. Glosario
6. Literatura & Enlaces

0. Introducción

Procedamos con la primera pregunta de la segunda parte del curso Twenty C# Questions Explained de Microsoft Virtual Academy. Aquí explicaremos el proceso de encriptación y descriptación de una cadena de caracteres (representada en un objeto String). Para ello utilizaremos una clase con los métodos para la encriptar una cadena de caracteres junto con una llave de protección representada también como una cadena caracteres que actuará como mecanismo simétrico para los usuarios (i.e., emisor y receptor) del sistema de comunicación hipotético que se simulará desde código cliente. ¡Manos a la obra!

1. Contexto

1.1 ¿Qué es la encriptación?

La encriptación es una técnica de protección de datos confidenciales que debe ser transmitidos por medios de comunicaciones de potencial vulnerabilidad. Estos datos podrían ser espiados y aprovechados por los atacantes de los datos generados y transmitidos por un emisor. A esta definición básica podemos agregar la hallada en [3]:
«En informática, convertir texto normal en un texto codificado de forma que las personas que no conozcan el código sean incapaces de leerlo.»
Lo que aquí nos están diciendo con texto normal, es texto legible y entendible por un humano o un sistema informático de comprensión semántica de textos; como estas mismas frases y párrafos que estamos escribiendo ahora mismo. El texto codificado corresponde con una representación alternativa segura e ilegible para cualquier parte que no cuente con el código (contraseña) de apertura/lectura.

En cuanto, a la operación inversa, descriptación, podemos recurrir a la definición encontrada en [4]:
«En inform., descodificar mediante las claves adecuadas la información que había se había encriptado.»
Con descodificar entendemos proveer una contraseña o código que revela el contenido real de la información transmitida. Si no proveemos las claves adecuadas el contenido será imposible de leer (esto es lo que brinda otra capa de seguridad frente a vectores de ataque). Evidentemente, para ejecutar esta operación, primero debemos tener datos encriptados con una técnica de encriptación (e.g., simétrica o asimétrica).

2. Encriptar y Desencriptar un Objeto String en .NET

Para que podamos entender cómo se lleva a cabo estas dos operaciones contextualizadas en la sección anterior, procedamos con los ejemplos de uso propuestos para esta pregunta C#.

2.1 Clase DESEncrypt

La clase DESEncrypt proveerá los elementos de programa (i.e., constructores y métodos públicos) para encriptar y desencriptar una cadena de caracteres especificada desde código cliente. (Aclaro que esta clase es una adaptación del código de ejemplo hallado en [1].)

En la líneas 14-21 de la clase DESEncrypt creamos el método CrearDES, con este método creamos la llave y el vector de inicialización que contiene los datos de seguridad para la encriptación y desencriptación. Esto lo logramos a través de la implementación concreta del algoritmo de cifrado Triple DES [5] en la clase TripleDESCryptoServiceProvider [6]. En el método EncriptarCadenaDeCaracteres (líneas 24-45) encriptamos un texto plano a través de las siguientes operaciones:
  • Línea 28: Creación de la representación en un arreglo de bytes de la cadena de caracteres contenida en textoPlano.
  • Línea 31: Creación de flujo en memoria principal a través de la clase MemoryStream [7].
  • Línea 34: Creación de de la clave segura con la invocación del método CrearDES.
  • Línea 37: Creación de una instancia de CryptoStream [8] para transformaciones criptográficas.
  • Línea 40: Escritura en memoria del arreglo de bytes. Aquí es donde finalmente se crea la versión encriptada de textoPlano como un flujo de bytes en memoria.
  • Línea 44: Retorna representación en cadena de caracteres de la versión encriptada de textoPlano.
En cuanto al método DesencriptarCadenaDeCaracteres, estas son las operaciones necesarias para desencriptar un texto encriptado:
  • Línea 52: Creación de la representación en un arreglo de bytes de la cadena de caracteres contenida en textoEncriptado.
  • Línea 55 Creación de flujo en memoria principal a través de la clase MemoryStream.
  • Línea 58Creación de de la clave segura con la invocación del método CrearDES basada en la contraseña contenida en el objeto string contrasegnia.
  • Línea 61: Creación del desencriptador.
  • Línea 64: Escritura en memoria de la versión desencriptada de textoEncriptado.
  • Línea 68: Conversión del flujo de datos en memoria a texto legible.

2.2 La clase de prueba PruebaEncriptacion

Ahora creamos una clase de prueba:

Archivo C# PruebaEncriptacion.cs [enlace alternativo]:

En la línea 9 creamos una instancia de string con la cadena de caracteres de prueba OrtizOL - Experiencias Construcción Software (xCS). En la línea 10 especificamos la contraseña con la que encriptaremos y desencriptaremos la cadena de caracteres (Nota: para propósitos de demostración la representación de la contraseña se ha hecho en texto plano, sin embargo para un ambiente de producción se recomienda utilizar prácticas de seguridad apropiadas). Sobre la línea 17 creamos una instancia de la clase DESEncrypt. Encriptamos la cadena de caracteres contenida en textoPlano invocando al método EncriptarCadenaDeCaracteres con la contraseña correspondiente: línea 20. Mostramos la representación textual del texto encriptado en la línea 22.


Más adelante, en la línea 26, invocamos al método DesencriptarCadenaDeCaracteres para desencriptar el texto encriptado en la variable string textoEncriptado. Mostramos el resultado de esta operación usando WriteLine de Console: línea 27.

Compilación:

1. Creación de librería a partir de la clase DESEncrypt:

  1. csc /target:library DESEncrypt.cs

2. Compilación de la clase de prueba PruebaEncriptacion:

  1. csc /target:exe /r:DESEncrypt.dll PruebaEncriptacon.cs

Ejecución assembly:

  1. .\PruebaEncriptacion.exe

> Prueba de ejecución:
Ejecución assembly PruebaEncriptacion.exe
Figura 1. Ejecución assembly PruebaEncriptacion.exe.

3. Recursos

Este es el vídeo en donde el equipo de expertos (Gerry O'Brein y Paul Pardi) de MVA responden y explican esta pregunta:

4. Conclusiones

Hemos visto cómo encriptar una cadena de caracteres usando varios de los artefactos y técnicas de encriptación que provee Microsoft .NET Framework. En especial, hemos utilizando el algoritmo Triple DES para la protección de códigos de acceso; además, hemos visto explorado otras construcciones útiles para la representación de texto como un flujo bytes y su representación en memoria principal. Estas últimas, necesarias para encriptar y desencriptar texto plano. Podemos concluir que la encriptación comprende un mecanismo de seguridad para proteger los datos de las aplicaciones, y sobretodo, los datos sensibles (credenciales de acceso a un portal corporativo, información personal o laboral, &c.) del usuario. En la siguiente pregunta C# cómo obtener el índice de un elemento en una iteración de ciclo foreach.

5. Glosario

  • Asimétrico
  • Cifrado
  • Cifrar
  • Contraseña
  • Encriptación
  • Desencriptación
  • Protección
  • Seguridad
  • Simétrico

6. Literatura & Enlaces

[1]: Twenty C# Questions Explained - http://www.microsoftvirtualacademy.com
[2]: Criptografía - Wikipedia, la enciclopedia libre - http://es.wikipedia.org/wiki/Criptograf%C3%ADa
[3]: encriptar - significado de encriptar diccionario - http://es.thefreedictionary.com/encriptar
[4]: Definición de desencriptar en EL PAÍS - http://servicios.elpais.com/diccionarios/castellano/desencriptar
[5]: Triple DES - Wikipedia, the free encyclopedia - https://en.wikipedia.org/wiki/Triple_DES
[6]: TripleDESCryptoServiceProvider Class (System.Security.Cryptography) - http://msdn.microsoft.com/en-us/library/system.security.cryptography.tripledescryptoserviceprovider(v=vs.110).aspx
[7]: MemoryStream Class (System.IO) - http://msdn.microsoft.com/en-us/library/system.io.memorystream(v=vs.110).aspx
[8]: CryptoStream Class (System.Security.Cryptography) - http://msdn.microsoft.com/en-us/library/system.security.cryptography.cryptostream(v=vs.110).aspx


J

1 comentario:

Envíe sus comentarios, dudas, sugerencias, críticas. Gracias.