Introducción:
En criptografía un cifrado, es un procedimiento que utilizando un algoritmo con cierta clave transforma un mensaje, sin atender a su estructura lingüística o significado, de tal forma que sea incomprensible o, al menos, difícil de comprender, a toda persona que no tenga la clave secreta del algoritmo que se usa para poder descifrarlo. Por tanto tenemos dos algoritmos (el de cifrado y el de descifrado) y dos claves (clave de cifrado y clave de descifrado). Estas dos claves pueden ser iguales (criptografía simétrica) o no (criptografía asimétrica).
Las diferencias entre ambas son en resumen:
Simétrica:
- Una misma clave para cifrado y decifrado.
- Es más rápido.
Asimétrica:
- Una clave pública para cifrar.
- Una clave privada para decifrar.
- Es más lento.
- Es más seguro que los algoritmos simétricos.
La clase FileSystemWatcher
Escucha las notificaciones de cambio del sistema de archivos y provoca eventos cuando cambia un directorio o un archivo de un directorio. En otras palabras es un monitor de archivos.Ejercicio práctico:
Para este tutorial de encriptar y desencriptar un archivo en .net, usaremos lo siguiente:- Visual Studio 2010
- Lenguaje C#
- Algoritmo de cifrado y decifrado DES
- Este algoritmo necesita una clave de 8 bytes ejm: "12345678", "abcdefgh", "clave123"
- Clase FileSystemWatcher
1. Lo primero será crear una aplicación de Consola en C# y darle nombre "ConsoleApplicationSeguro_SLN".
2. Crear 2 clases y nombrarlas: "Encriptar.cs" y "Watcher.cs".
3. La clase Watcher será nuestro monitor de archivos y tendrá el siguiente código:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using System.Diagnostics; namespace ConsoleApplicationSeguro { public class Watcher { public string llave { get; set; } public void Run(string ruta) { Console.WriteLine("Directorio a monitorear: " + ruta); FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Path = ruta; // Monitorea cambios como último acceso y última modificación de archivos y directorios. watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName; // Seteamos el filtro para todos los archivos. watcher.Filter = "*.*"; // Agrego manejadores de eventos "Handlers". watcher.Created += new FileSystemEventHandler(OnCreated); // Empieza el monitoreo. watcher.EnableRaisingEvents = true; // Preguntar si desea salir del monitoreo. Console.WriteLine("Presione \'q\' para salir del monitoreo."); while (Console.ReadLine() != "q") ; } // Definir los handlers. private void OnCreated(object source, FileSystemEventArgs e) { // Instrucciones que se debe realizar cuando se dispara el evento: Encriptar en = new Encriptar(); Console.WriteLine("Archivo: " + e.FullPath); if (e.FullPath.Substring(e.FullPath.Length - 3, 3).ToString() != "cfr") { Console.WriteLine("Encriptando el archivo: " + e.FullPath); FileStream archivo = new FileStream(e.FullPath, FileMode.Open, FileAccess.ReadWrite); en.CifrarArchivo(archivo, llave); } } } }
La clase "Encriptar.cs" se encarga de cifrar y decifrar archivos de todo tipo con el siguiente código:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.IO; namespace ConsoleApplicationSeguro { public class Encriptar { #region "Cifrado de Archivos" public void CifrarArchivo(FileStream archivo, string key) { DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] keyBytes = Encoding.UTF8.GetBytes(key); des.Key = keyBytes; key = Convert.ToBase64String(keyBytes); des.Mode = CipherMode.ECB; ICryptoTransform encryptor = des.CreateEncryptor(); //crea un byte array de longitud del mismo archivo byte[] archivoBytes = new byte[archivo.Length]; archivo.Read(archivoBytes,0,(int)archivo.Length); archivo.Close(); //encriptando byte[] dataEncrypted = encryptor.TransformFinalBlock(archivoBytes, 0, archivoBytes.Length); FileStream archivoEncriptado = new FileStream(archivo.Name + ".cfr", FileMode.Create, FileAccess.Write); archivoEncriptado.Write(dataEncrypted, 0, (int)dataEncrypted.Length); archivoEncriptado.Close(); } public void DecifrarArchivos(FileStream archivo, string key, string rutaDestino, ref string mensaje) { try { mensaje = ""; DESCryptoServiceProvider des = new DESCryptoServiceProvider(); byte[] keyBytes = Encoding.UTF8.GetBytes(key); key = Convert.ToBase64String(keyBytes); des.Key = Convert.FromBase64String(key); des.Mode = CipherMode.ECB; ICryptoTransform decryptor = des.CreateDecryptor(); //crea un byte array de longitud del mismo archivo byte[] archivoBytes = new byte[archivo.Length]; archivo.Read(archivoBytes, 0, (int)archivo.Length); archivo.Close(); //Decriptando byte[] dataDecrypted = decryptor.TransformFinalBlock(archivoBytes, 0, archivoBytes.Length); FileStream archivoDesEncriptado = new FileStream(rutaDestino + Path.GetFileName(archivo.Name.Substring(0, archivo.Name.Length - 4)), FileMode.Create, FileAccess.Write); archivoDesEncriptado.Write(dataDecrypted, 0, (int)dataDecrypted.Length); archivoDesEncriptado.Close(); mensaje = "Descifrado correctamente"; } catch (CryptographicException ex) { mensaje = ex.Message; } catch (ArgumentException ex) { mensaje = ex.Message; } } #endregion public bool validaKey(string llave) { byte[] keyBytes = Encoding.UTF8.GetBytes(llave); if (keyBytes.Length == 8) return true; else return false; } } }
Bien ahora solo falta llamar a las funciones en el Main desde la clase "Program.cs":
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace ConsoleApplicationSeguro { class Program { static void Main(string[] args) { Encriptar en = new Encriptar(); Watcher w = new Watcher(); string llave; string rutaOrigen = "K:/Seguro/"; string rutaDestino = "K:/Inseguro/"; string mensaje = ""; Console.WriteLine("******* SISTEMA DE CIFRADO Y DESCIFRADO WILLSECURITY *******"); Console.Write("\n Ingrese la llave para la encriptación: "); llave = Console.ReadLine(); while (en.validaKey(llave) == false) { Console.WriteLine("La llave ingresada no es soportada"); Console.Write("Ingrese la llave:"); llave = Console.ReadLine(); } w.llave = llave; //Aqui empieza a monitorear eventos de creacion de archivos en el directorio w.Run(rutaOrigen); Console.WriteLine("Encriptaciòn Completada"); //Aqui Pregunta si deseas desencriptar Console.Write("Desea desencriptar archivos? s/n : "); while (Console.ReadLine() == "s") { Console.Write("Nombre de archivo: "); string archivo = rutaOrigen + Console.ReadLine(); Console.Write("Clave de descifrado: "); string clave = Console.ReadLine(); if (File.Exists(archivo)) { FileStream archivoCifrado = new FileStream(archivo, FileMode.Open, FileAccess.ReadWrite); Console.WriteLine("Desencriptando el archivo: " + archivo); en.DecifrarArchivos(archivoCifrado, clave, rutaDestino, ref mensaje); Console.WriteLine(mensaje); } else Console.WriteLine("Archivo no existe"); Console.Write("Desea desencriptar otro archivo? S/N : "); } Console.ReadKey(); } } }
Compilarlo y ejecutarlo.
A continuación algunas imágenes de la ejecución:
1. La aplicación solicita llave para cifrar, recordar que debe ser de 8 bytes
2. Nos indica que está monitoreando el directorio "K:/Seguro/"
4. Presionamos "q" para salir del monitoreo. Y nos pregunta si queremos decifrar algún archivo. Tecleamos "s" y damos enter
5. Nos solicita el nombre del archivo .cfr y la llave de decifrado, recordar que para este algoritmo la llave de cifrado y decifrado es la misma porque es un algoritmo simétrico.
Automáticamente procederá a decifrar el archivo y lo pondrá en el directorio seteado "K:/Inseguro/"
6. Para finalizar la aplicación teclear "n" y dar enter.
En conclusión:
La encriptación, es un método para el traspaso de información sensible y existen variedades de algoritmos para cada caso según la lógica del negocio, el programador deberá elegir el algoritmo que más le convenga a la empresa.El uso de la clase FileSystemWatcher, puede ser un excelente monitor de archivos y se puede combinar con otras técnicas como la encriptación.
Comentarios
Publicar un comentario