Está en la página 1de 12

Programacin III, Gua 10

Facultad : Ingeniera Escuela : Computacin Asignatura: Programacin III Tema: ENCRIPTACIN.

Objetivo
Aplicar tcnicas de encriptamiento con el fin de comprender su funcionamiento.

Introduccin
Encriptacin Simtrica con C#. Cuando dos partes remotas intercambian datos a travs de un canal inseguro (como por ejemplo), ambas partes deben garantizar que los datos comunicados: No puedan ser comprendidos por nadie que pueda estar escuchando: Confidencialidad. No han sido modificados durante la trasmisin: Integridad. Provienen realmente de quin provienen y no de nadie que haya suplantado la identidad de una de las dos partes: Autenticacin.

La criptografa se utiliza para lograr estos objetivos. Para alcanzarlos es necesario la combinacin de una serie de primitivas criptogrficas. Aunque este tema da la sensacin de ser complejo, en realidad, no es necesario saber cmo funcionan los algoritmos de encriptacin. El truco es saber usarlos sin ms y evitar malas prcticas. Consejo: Cualquier algoritmo que cambie de cierta manera un texto no se puede considerar un algoritmo encriptado, sino simplemente transformador (por ejemplo, aplicar un XOR a una cadena de texto produce un resultado que, como no lo entendemos, creemos que la informacin est encriptado, cuando en realidad un hacker podra obtener la informacin fcilmente). As que, si vamos a proteger informacin, debe hacerse con algoritmos probados. 1 Primitiva criptogrfica: La encriptacin simtrica o cifrado de clave secreta. En la encriptacin simtrica se utiliza una nica clave secreta para cifrar y descifrar los datos (de ah la denominacin de simtrica). Son algoritmos muy rpidos, por eso se utilizan para grandes secuencias de datos. Dentro de los algoritmos de encriptacin simtrica podemos encontrar los siguientes (algunos ms seguros que otros).

Programacin III, Gua 10 2 DES (Digital Encryption Standard) 3DES (Three DES o Triple DES) IDEA (International Data Encryption Algorithm) AES (Advanced Encryption Standard)

AES, tambin conocido como Rijndael (aunque no son exactamente lo mismo), es de amplia aceptacin a nivel mundial. Hoy en da es el ms seguro y rpido. Cualquiera de estos algoritmos utiliza los siguientes dos elementos (ninguno de los dos debe pasarse por alto ni subestimarse su importancia): IV (Vector de inicializacin). No se puede encriptar sin l. Es de 16 bytes de longitud para el algoritmo de Rijndael. No es una 2 llave, por lo tanto, no se trata de una dato que haya que esconder, nicamente hay que considerar que hay que usar el mismo IV para encriptar/desencriptar un mensaje concreto. Un error comn es utilizar el mismo vector de inicializacin en todas las encriptaciones. Utilizar siempre un mismo IV es equivalente en seguridad a no utilizar encriptacin. Key (llave). Esta es la principal informacin para encriptar / desencriptar en los algoritmos simtricos. Toda la seguridad de un sistema simtrico depende de dnde est esta llave, cmo est compuesta y quin tiene acceso. ste es un dato que debe conocerse nica y exclusivamente por los interlocutores de la comunicacin. De otra forma, la seguridad en la comunicacin se vera comprometida.

Ejemplo de funcionamiento.
Ana y Jos acuerdan utilizar un algoritmo en particular con una clave y vector de inicializacin concretos. Ana redacta un mensaje y cifra el texto usando la clave y el vector de inicializacin y se lo enva a Jos por Internet. Jos recibe el texto cifrado y lo descifra utilizando la clave y el vector acordados anteriormente.

Si se intercepta la transmisin, el interceptor no podr recuperar el mensaje original porque no conoce la clave ni el vector.

Consideraciones acerca de la clave.


Cuanto ms grande sea el tamao de la llave, ms difcil ser obtenerla mediante un ataque por fuerza bruta. Para el algoritmo de Rijndael, las claves pueden ser de 128, 192 y 256 bits de longitud. Por ejemplo, para una clave de 64 bits de longitud, a un ritmo de comprobacin de 50 claves por segundo, podra llevar unos 11,6 billones de aos en comprobar todos los valores posibles de la clave.

Programacin III, Gua 10 3

Consideraciones acerca del vector de inicializacin.


En un esquema de cifrado por bloques (como Rijndael), la secuencia de texto sin cifrar se parte en bloques para su procesamiento. Para una clave secreta determinada, un cifrado que no utilice un vector de inicializacin codificar el mismo bloque de entrada de texto sin cifrar en el mismo bloque de salida de texto cifrado. Si hay bloques duplicados dentro la secuencia de texto a cifrar, habr bloques duplicados en la secuencia de texto cifrado. Si el hacker sabe algo acerca de la estructura de un bloque del texto sin cifrar, puede utilizar esa informacin para descifrar el bloque de texto cifrado conocido y, posiblemente, recuperar la clave. Para combatir este problema, la informacin del bloque anterior se mezcla en el proceso de cifrado del bloque siguiente. As pues, el resultado de dos bloques idnticos de texto sin cifrar es distinto. Como esta tcnica utiliza el bloque anterior para cifrar el bloque siguiente, se utiliza un IV para cifrar el primer bloque de datos. Con este sistema, los encabezados de los mensajes comunes que un hacker podra conocer no pueden utilizarse para aplicar tcnicas de ingeniera inversa en una clave.

Consideraciones acerca del modo de cifrado


Los algoritmos de cifrado de bloque como DES o AES separan el mensaje en bloques de tamao fijo para su procesamiento, por ejemplo 128 bits. La forma en que se gestionan estos bloques se denomina modo de cifrado. Los modos de cifrado que soporta .NET Framework son ECB, CBC, y CFB (es preferible usar CBC).

Modos de relleno.
La mayora de los mensajes de texto a cifrar no contienen los bytes necesarios para rellenar totalmente los bloques. A menudo, no hay bytes suficientes para rellenar el ltimo bloque. Cuando esto sucede, se agrega una cadena de relleno al texto. Por ejemplo, si la longitud del bloque es de 64 bits y el ltimo bloque slo contiene 40 bits, se agregan 24 bits de relleno. .NET Framework soporta dos modos de relleno: Zeros: La cadena de relleno consta de bytes establecidos en cero. PKCS7: La cadena de relleno PKCS #7 consta de una secuencia de bytes, en la que cada byte es igual al nmero total de bytes de relleno agregados.

Materiales y equipo
Gua de Laboratorio N 10. Computadora con programa: o Visual Studio 2005. C# Dispositivo de Almacenamiento (USB).

Programacin III, Gua 10 4

Procedimiento
Ejemplo 1: Cree un proyecto modo consola en C# .NET. Con el nombre de encryption.
using using using using using System; System.Collections.Generic; System.Text; System.IO; System.Security.Cryptography;

namespace encryption { class Program { static string encriptar(string cadena, string clave) { // Aqui va el codigo de la funcion encriptar // Convierto la cadena y la clave en arreglos de bytes // para poder usarlas en las funciones de encriptacion byte[] cadenaBytes = Encoding.UTF8.GetBytes(cadena); byte[] claveBytes = Encoding.UTF8.GetBytes(clave); // Creo un objeto de la clase Rijndael RijndaelManaged rij = new RijndaelManaged(); // Configuro para que utilice el modo ECB rij.Mode = CipherMode.ECB; // Configuro para que use encriptacion de 256 bits. rij.BlockSize = 256; // Declaro que si necesitara mas bytes agregue ceros. rij.Padding = PaddingMode.Zeros; // Declaro un encriptador que use mi clave secreta y un vector // de inicializacion aleatorio ICryptoTransform encriptador; encriptador = rij.CreateEncryptor(claveBytes, rij.IV); // Declaro un stream de memoria para que guarde los datos // encriptados a medida que se van calculando MemoryStream memStream = new MemoryStream(); // Declaro un stream de cifrado para que pueda escribir aqui // la cadena a encriptar. Esta clase utiliza el encriptador // y el stream de memoria para realizar la encriptacion // y para almacenarla CryptoStream cifradoStream; cifradoStream = new CryptoStream(memStream, encriptador, CryptoStreamMode.Write); // Escribo los bytes a encriptar. A medida que se va escribiendo // se va encriptando la cadena cifradoStream.Write(cadenaBytes, 0, cadenaBytes.Length);

Programacin III, Gua 10 5

// Aviso que la encriptacin se termin cifradoStream.FlushFinalBlock(); // Convert our encrypted data from a memory stream into a byte array. byte[] cipherTextBytes = memStream.ToArray(); // Cierro los dos streams creados memStream.Close(); cifradoStream.Close(); // Convierto el resultado en base 64 para que sea legible // y devuelvo el resultado return Convert.ToBase64String(cipherTextBytes); }

static string desencriptar(string cadena, string clave) { // Aqui va el codigo de la funcion desencriptar // Convierto la cadena y la clave en arreglos de bytes // para poder usarlas en las funciones de encriptacion // En este caso la cadena la convierta usando base 64 // que es la codificacion usada en el metodo encriptar byte[] cadenaBytes = Convert.FromBase64String(cadena); byte[] claveBytes = Encoding.UTF8.GetBytes(clave); // Creo un objeto de la clase Rijndael RijndaelManaged rij = new RijndaelManaged(); // Configuro para que utilice el modo ECB rij.Mode = CipherMode.ECB; // Configuro para que use encriptacion de 256 bits. rij.BlockSize = 256; // Declaro que si necesitara mas bytes agregue ceros. rij.Padding = PaddingMode.Zeros; // Declaro un desencriptador que use mi clave secreta y un vector // de inicializacion aleatorio ICryptoTransform desencriptador; desencriptador = rij.CreateDecryptor(claveBytes, rij.IV); // Declaro un stream de memoria para que guarde los datos // encriptados MemoryStream memStream = new MemoryStream(cadenaBytes); // Declaro un stream de cifrado para que pueda leer de aqui // la cadena a desencriptar. Esta clase utiliza el desencriptador // y el stream de memoria para realizar la desencriptacion CryptoStream cifradoStream; cifradoStream = new CryptoStream(memStream, desencriptador, CryptoStreamMode.Read);

Programacin III, Gua 10 6

// Declaro un lector para que lea desde el stream de cifrado. // A medida que vaya leyendo se ira desencriptando. StreamReader lectorStream = new StreamReader(cifradoStream); // Leo todos los bytes y lo almaceno en una cadena string resultado = lectorStream.ReadToEnd(); // Cierro los dos streams creados memStream.Close(); cifradoStream.Close(); // Devuelvo la cadena return resultado; } static void Main(string[] args) { // La clave tiene que tener 32 caracteres para // la encriptacion de 256 bits. string clave_secreta = "clave_de_32_caracteres_obligado."; string valorEncriptado = encriptar("Hola", clave_secreta); string valorDesencriptado = desencriptar(valorEncriptado, clave_secreta); Console.WriteLine(valorEncriptado); Console.WriteLine(valorDesencriptado); Console.ReadLine(); } } }

Ejemplo 2. Cree un proyecto modo consola en C# .NET. Con el nombre de miEjemplo.


using using using using using System; System.IO; System.Security.Cryptography; System.Collections.Generic; System.Text;

namespace miEjemplo { class Program { static void Main(string[] args) { // Este es el mensaje que vamos a encriptar. string mensaje = "Programando seguridad en C#.NET"; Console.WriteLine("Esto es el mensaje sin cifrar: " + mensaje); Console.WriteLine("Pulse una tecla para continuar\n"); Console.ReadKey();

Programacin III, Gua 10 7

// Creamos el algoritmo encriptador SymmetricAlgorithm algoritmo = SymmetricAlgorithm.Create("Rijndael"); //Se podra haber creado el algoritmo de esta otra manera: //RijndaelManaged algoritmoEncriptador = new RijndaelManaged(); ConfigurarAlgoritmo(algoritmo); GenerarClave(algoritmo); GenerarIV(algoritmo); byte[] mensajeEncriptado = Encriptar(mensaje, algoritmo); Console.WriteLine("Esto es el mensaje cifrado:"); foreach (byte b in mensajeEncriptado) { Console.Write("{0:X2} ", b); } Console.WriteLine("\nPulse una tecla para continuar\n"); Console.ReadKey(); byte[] mensajeDesencriptado = Desencriptar(mensajeEncriptado, algoritmo); string mensajeDescrifrado = Encoding.UTF8.GetString(mensajeDesencriptado); Console.WriteLine("Esto es el mensaje descifrado: " + mensajeDescrifrado); Console.WriteLine("Pulse una tecla para terminar\n"); Console.ReadKey(); algoritmo.Clear(); } private static void ConfigurarAlgoritmo(SymmetricAlgorithm algoritmo) { // Cambiamos el valor del tamao de bloque algoritmo.BlockSize = 128; // Establecemos el modo de cifrado y con el modo de relleno algoritmo.Mode = CipherMode.CBC; algoritmo.Padding = PaddingMode.PKCS7; Console.WriteLine("Longitud de bloque: {0}", algoritmo.BlockSize); Console.WriteLine("Modo de cifrado: {0}", algoritmo.Mode); Console.WriteLine("Modo de relleno: {0}", algoritmo.Padding); Console.WriteLine("Pulse una tecla para continuar\n"); Console.ReadKey(); } private static void GenerarClave(SymmetricAlgorithm algoritmo) { // Establecemos la longitud que queremos que tenga la clave a generar. algoritmo.KeySize = 256; Console.WriteLine("Longitud de la clave: {0}", algoritmo.KeySize); Console.WriteLine("Pulse una tecla para continuar\n"); Console.ReadKey(); // Leer sin ms el valor de la clave hara que se genere. // sacamos la clave por consola Console.WriteLine("La clave: ");

Programacin III, Gua 10 8

foreach (byte b in algoritmo.Key) { Console.Write("{0:X2} ", b); } Console.WriteLine("\nPulse una tecla para continuar\n"); Console.ReadKey(); // Podemos generar otra nueva algoritmo.GenerateKey(); // sacamos la nueva clave por consola Console.WriteLine("Otra clave: "); foreach (byte b in algoritmo.Key) { Console.Write("{0:X2} ", b); } Console.WriteLine("\nPulse una tecla para continuar\n"); Console.ReadKey(); // Otra forma de crear claves sera con RNG (Random Number Generator) RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create(); // Se rellena el array de bytes de la clave con datos aleatorios randomNumberGenerator.GetBytes(algoritmo.Key); // sacamos la clave por consola Console.WriteLine("Otra forma de obtener una clave: "); foreach (byte b in algoritmo.Key) { Console.Write("{0:X2} ", b); } Console.WriteLine("\nPulse una tecla para continuar\n"); Console.ReadKey(); }

private static void GenerarIV(SymmetricAlgorithm algoritmo) { // Si haces lo siguiente se genera un nuevo IV algoritmo.GenerateIV(); // sacamos el IV por consola Console.WriteLine("IV (Vector de inicializacin): "); foreach (byte b in algoritmo.IV) { Console.Write("{0:X2} ", b); } Console.WriteLine("\nPulse una tecla para continuar\n"); Console.ReadKey(); }

Programacin III, Gua 10 9

public static byte[] Encriptar(string mensajeSinEncriptar, SymmetricAlgorithm algoritmo) {


// La clase SymmetricAlgorithm delega el proceso de encriptacin de datos // a la interfaz ICryptoTransform, la cual expone los detalles en el manejo de bloques. // Una instancia de ICryptoTransform transforma texto plano en texto cifrado o vice versa. // Las siguiente sentencia demuestra como crear transformaciones usando CreateEncryptor. // Crear una ICryptoTransform que puede ser usada para encriptar datos

ICryptoTransform encriptador = algoritmo.CreateEncryptor(); // Las instancias de la interfaz ICryptoTransform no son tiles en si mismas. // .NET framework provee la clase CryptoStream para el manejo de instancias de la interfaz ICryptoTransform. // La clase CryptoStream actua como un envoltorio sobre un stream y transforma // automticamente bloques de datos usando una interfaz ICryptoTransform. // La clase CryptoStream transforma datos ledos de un stream // (por ejemplo, desencriptando texto cifrado de un fichero) // o escribiendo en un stream (por ejemplo, encriptando datos generados por programa // y almacenando el resultado en un fichero). // Crear instancias de la clase CryptoStream requiere un stream real, // una instancia de la interfaz ICryptoTransform // y un valor de la enumeracion CryptoStreamMode // Obtenemos los bytes que representan el mensaje a encriptar byte[] textoPlano = Encoding.Default.GetBytes(mensajeSinEncriptar); // Creamos un MemoryStream MemoryStream memoryStream = new MemoryStream(); // Cualquier operacin de encriptacin/desencriptacin hara que la clase // que implemente el algoritmo simtrico genere una nueva clave e IV // si dichos valores no han sido establecidos // Creamos el CryptoStream CryptoStream cryptoStream = new CryptoStream(memoryStream, encriptador, CryptoStreamMode.Write); // Escribimos el textoPlano hacia el CryptoStream cryptoStream.Write(textoPlano, 0, textoPlano.Length); // Terminamos la operacin de encriptacin. cryptoStream.FlushFinalBlock(); // Liberamos. memoryStream.Close(); cryptoStream.Close(); // Obtenemos el texto cifrado del MemoryStream return memoryStream.ToArray(); }

Programacin III, Gua 10 10

public static byte[] Desencriptar(byte[] mensajeEncriptado, SymmetricAlgorithm algoritmo) { int numeroBytesDesencriptados = 0; // La clase SymmetricAlgorithm delega el proceso de desencriptacin de datos // Una instancia de ICryptoTransform transforma texto plano en texto cifrado o vice versa. // Las siguiente sentencia demuestra como crear transformaciones usando CreateDecryptor. byte[] mensajeDesencriptado = new byte[mensajeEncriptado.Length]; // Crear una ICryptoTransform que puede ser usada para desencriptar datos ICryptoTransform desencriptador = algoritmo.CreateDecryptor(); // Procedemos a descifrar el mensaje MemoryStream memoryStream = new MemoryStream(mensajeEncriptado); // Creamos el CryptoStream CryptoStream cryptoStream = new CryptoStream(memoryStream, desencriptador, CryptoStreamMode.Read); // Decrypting data and get the count of plain text bytes. numeroBytesDesencriptados = cryptoStream.Read(mensajeDesencriptado, 0, mensajeDesencriptado.Length); // Liberamos recursos. memoryStream.Close(); cryptoStream.Close(); return mensajeDesencriptado; } } }

Programacin III, Gua 10 11

Anlisis de resultados
En base a los programas dados en la prctica, modifquelo de manera que el mensaje a cifrar pueda ser ingresado por el usuario (de forma manual) Ahora que los mensajes pueden ser ingresados por el usuario, compare introduciendo mensajes de diferente longitudes. Cambia la longitud del mensaje cifrado?Por qu tiene esa longitud? Consideran qu es seguro? Para el ejercicio 2, cuando se ejecuta manda tres mensajes de Clave, otra clave y otra manera de obtener la clave Qu representan dichas claves?

Investigacin complementaria.
Investigue cmo funciona el modo de cifrado CBC, qu es utilizado en esta gua, adems como tiene relacin con el modo de relleno PKCS7. Presente un caso de aplicacin real en el cual se haya utilizado este tipo de cifrado.

Referencia.

http://elburgues.wordpress.com/2010/03/13/encriptacionsimetrica-en-c/ http://copstone.com/2010/03/encriptacion-en-c-sharp/

Programacin III, Gua 10 12

Hoja de cotejo:

10 1

Gua 10: Encriptacin.

Alumno: Docente:

Mquina No: GL: Fecha:

EVALUACION % 1-4 5-7 8-10 Nota

CONOCIMIENTO

40

APLICACIN DEL CONOCIMIENTO

40

ACTITUD 20

TOTAL 100%

También podría gustarte