Blog de programación, donde ademas de encontrar pequeños programas en C# tambien publicaré pequeñas ayudas para SQL Server

Vladimir Miranda - vladivirus666@gmail.com. Con la tecnología de Blogger.

lunes, 19 de octubre de 2015

Encriptar informacion (Nativo)


Empiezo con otro post, ahora con respecto a la encriptación de informacion. Muchas veces necesitamos que la informacion que nosotros enviamos, recibimos o almacenamos se encuentre disponible solo para el usuario que la genero.

Puede ser informacion delicada y/o crítica como contraseñas, datos personales, etc. Navegando un poco en internet me encontre que hay como realizar esta accion desde C# sin necesidad de ninguna librería de terceros.

Antes de nada indicar que para este tutorial necesitaremos de una clave con la cual podremos encriptar y desencriptar la informacion.

System.Security.Cryptography

Para este post vamos a utilizar la librería System.Security.Cryptography la cual hará todo el trabajo pesado, de esta librería utilizamos MD5CryptoServiceProvider. Que es MD5 (Clase):

Representa la clase abstracta desde la que se heredan todas las implementaciones del algoritmo hash MD5. Mas info aquí 
 Adicional para cifrar la informacion utilizamos TripleDESCryptoServiceProvider para especificar el modo de cifrado de bloques y el tipo de relleno que vamos a utilizar. Podemos ver mas información de esto en estos enlaces:

CipherMode

Padding Mode

Ahora a lo que nos compete; voy a generar una biblioteca de Clases, en mi caso le he puesto el nombre de EncriptarDesencriptarInformacion, mi clase contiene un constructor para el ingreso de la clave con la que se va a encriptar la informacion.

01 
02         private string clave;
03 
04         /// <summary>
05         /// Constructor que define la clave a utilizarse para encriptar la información
06         /// </summary>
07         /// <param name="claveEncriptacion">clave de encriptacion</param>
08         public EncriptarDatos(string claveEncriptacion)
09         {
10             this.clave = claveEncriptacion;
11         }

También he creado una clase encriptar datos la cual nos ayudará a cifrar la informacion.

01 
02         /// <summary>
03         /// Metodo para encriptar la informacion
04         /// </summary>
05         /// <param name="informacion">Informacion que se quiere encriptar</param>
06         /// <returns></returns>
07         public string Encriptar(string informacion)
08         {
09             //Aqui guardamos la clave con la que vamos a cifrar
10             byte[] arrayClave;
11 
12             //Aqui guardamos el texto a cifrar
13             byte[] arregloDeInformacion = UTF8Encoding.UTF8.GetBytes(informacion);
14 
15             //Se utiliza System.Security.Cryptography para MD5 
16             MD5CryptoServiceProvider variableHashMD5 = new MD5CryptoServiceProvider();
17 
18             //Se hace el hash con la clave
19             arrayClave = variableHashMD5.ComputeHash(UTF8Encoding.UTF8.GetBytes(clave));
20 
21             variableHashMD5.Clear();
22 
23             TripleDESCryptoServiceProvider cifradoTripleDES = new TripleDESCryptoServiceProvider();
24 
25             cifradoTripleDES.Key = arrayClave;
26             cifradoTripleDES.Mode = CipherMode.ECB; //Especifica el modo de cifrado de bloques que se utilizará para cifrar
27             cifradoTripleDES.Padding = PaddingMode.PKCS7; //Especifica el tipo de relleno que se aplica cuando el bloque de datos del mensaje es más pequeño que el número total de bytes necesarios para una operación criptográfica.
28 
29             ICryptoTransform cTransform = cifradoTripleDES.CreateEncryptor();
30 
31             byte[] resultadoEncriptacion = cTransform.TransformFinalBlock(arregloDeInformacion, 0, arregloDeInformacion.Length);
32 
33             cifradoTripleDES.Clear();
34 
35             return Convert.ToBase64String(resultadoEncriptacion, 0, resultadoEncriptacion.Length);
36         }

Y por último una clase para desencriptar la información:

01 
02         /// <summary>
03         /// Metodo para desencriptar la informacion
04         /// </summary>
05         /// <param name="informacionEncriptada">Información que se va a desencriptar</param>
06         /// <returns>variables desencriptada</returns>
07         public string Desencriptar(string informacionEncriptada)
08         {
09             byte[] arrayClave;
10             
11             byte[] arregloDeInformacinoEncriptada = Convert.FromBase64String(informacionEncriptada);
12 
13             MD5CryptoServiceProvider variableHashMD5 = new MD5CryptoServiceProvider();
14 
15             arrayClave = variableHashMD5.ComputeHash(UTF8Encoding.UTF8.GetBytes(clave));
16 
17             variableHashMD5.Clear();
18 
19             TripleDESCryptoServiceProvider cifradoTripleDES = new TripleDESCryptoServiceProvider();
20 
21             cifradoTripleDES.Key = arrayClave;
22             cifradoTripleDES.Mode = CipherMode.ECB;
23             cifradoTripleDES.Padding = PaddingMode.PKCS7;
24 
25             ICryptoTransform cTransform = cifradoTripleDES.CreateDecryptor();
26 
27             byte[] resultadoDesencriptacion = cTransform.TransformFinalBlock(arregloDeInformacinoEncriptada, 0, arregloDeInformacinoEncriptada.Length);
28 
29             cifradoTripleDES.Clear();
30             
31             return UTF8Encoding.UTF8.GetString(resultadoDesencriptacion);
32         }
33     }

Hay que tomar en cuenta que, una vez ingresada la clave para encriptar; esta será la única para poder desencriptar.

Para complementar les dejo la dll para los que quieren saltarse el paso de copiar el código, esta hecho en VS13 Framework 4.5.1


COMO EXPORTAR CLAVES PRIVADAS QUE SE HAN MARCADO COMO NO-EXPORTABLES (JailBreak)








En Ecuador contamos con facturación electrónica; si tenemos un proveedor externo que nos ayuda con este proceso, en algun momento nos solicita un certificado digital, en mi caso me han solicitado un archivo *.pfx (Intercambio de información personal), en fin, mi emisor de certificados digitales me entrego un archivo con la extensión *.p12; estos certificados son faciles de cambiar con unos cortos pasos:

Antes de empezar quiero dejar claro que al colocar JailBreak este post no trata nada acerca de Iphone o Ipody un largo etcetera con respecto a todo lo que tiene que ver con la manzanita

Presionamos las teclas Windows + R y escribimos mmc (Microsoft Management Console), luego damos Enter


Una  vez en la consola damos clic en Archivo y despues en Agregar o quitar complemento...



Buscamos en los complementos el apartado de Certificados, damos doble clic y se nos muestra una nueva pantalla. Si estamos en la maquina como Administrados debemos dejar que el complemento se administre desde "Mi cuenta de usuario" (Mas informacion sobre este tema aqui)


Damos clic en finalizar y en la parte izquierda de la consola podremos ver un nuevo items que corresponde al certificado, y en la parte derecha las carpetas donde se encuentran todos los certificados; en mi caso guarde los certificados en personal. Ahi los voy a revisar y exportar los que desee.


Cuando tengamos nuestro certificado, damos clic derecho en el mismo, clic en Todas las tareas y Exportar.


Ahora el problema se da cuando al exportar la opción "Exportar Clave Privada" no se encuentra activa y no podemos convertirlo a pfx.


Para esto usaremos un programa llamado JailBreak que nos permitirá exportar el archivo a pesar de que la clave privada este marcada como no exportable. En cuanto tenemos el archivo zip, lo descomprimimos, de preferencia lo vamos a colocar en un directorio raiz (a su elección); para mi ejemplo voy a colocarlo en C:

Ahora, vamos a abrir una consola de comandos (la ejecutamos como Administrador) y nos colocamos en el directorio binaries que se encuentra dentro de la carpeta; en mi ejemplo ejecuto cd C:\jailbreak-master\binaries


Ahora ejecutamos el siguiente comando

jailbreak64.exe %WINDIR%\system32\mmc.exe %WINDIR%\system32\certmgr.msc -64

Al ejecutar este comando estamos invocando a una instancia de gestión mmc (Microsoft Management Console) pero con el parche que realiza el dll de la aplicación.

Volvemos a realizar los pasos descritos en este mismo blog para exportar el certificado; pero ahora podremos ver que ya se encuentra habilitada la opción de "Exportar la clave privada"


Damos clic en la opcion y despues en Siguiente, verificamos que la opcion "" se encuentre activa y seleccionada y damos clic en Siguiente.


Ingresamos la contraseña del certificado y damos clic en siguiente.


Damos clic a examinar para seleccionar la ubicacion donde queremos guardar nuestro documento, damos clic en Siguiente y Finalizar. Si todo el proceso se cumplió con normalidad tendremos un mensaje de confirmacion.


Y eso seria todo con respecto a la exportacion del certificado