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