Criptografia

No cabe duda de que los últimos tiempos están marcados por un nivel de paranoia adicional en cuanto a la vigilancia, la

Views 640 Downloads 2 File size 524KB

Report DMCA / Copyright

DOWNLOAD FILE

Recommend stories

Citation preview

No cabe duda de que los últimos tiempos están marcados por un nivel de paranoia adicional en cuanto a la vigilancia, la seguridad y privacidad de nuestra información. Ahí están la NSA, Snowdeny toda una plétora de fallos de seguridad en importantes librerías, aplicaciones y dispositivos que (intencionados o no), nos recuerdan que siempre deberíamos de poner un poco de cuidado adicional cuando de lo que se trata es de crear aplicaciones seguras, y más aún si estas están circunscritas al ámbito web. Precisamente para ayudarnos en esas tareas tenemos a nuestra disposición la capacidad de cifrar la información, aplicar firmas digitales, o bien generar huellas únicas para un conjunto dado de datos mediante una amplia variedad de algoritmos y sistemas criptográficos. Y si te interesa el tema, he de recomendarte un par de libros que, en mi opinión, son esenciales: "Cryptography Engineering: Design Principles and Practical Applications" (Niels Ferguson, Niels, Schneier, Bruce and Kohno, Tadayoshi y "Applied Cryptography: Protocols, Algorithms, and Source Code in C" (Schneier, Bruce). Hash y RSA fácil Ahora bien, como en otras tantas cosas, el enfoque propuesto por Xojo es el de facilitarnos al máximo y a un punto realmente transparente todas las operaciones que, por otra parte, podrían resultar un tanto farragosas o requerir de unos conocimientos elevados. (Recuerda que la filosofía de Xojo es la de poner las herramientas de programación al alcance de cualquier usuario, al tiempo que los desarrolladores avanzados encuentren también herramientas y características potentes que les permita crear todo tipo de aplicaciones.) Así, a partir de la versión Xojo 2013r4.1 (diciembre de 2013) encontramos en el lenguaje un completo conjunto de funciones criptográficas basadas en la librería Crypto++ 5.6.2 donde se exponen para su uso en aplicaciones multiplataforma (WIndows, OS X, Linux y Web) los algoritmos de Hash o huellas únicas correspondientes a MD5 y SHA en sus variantes SHA1, SHA256 y SHA512, diseñadas por la NSA por cierto. En cuanto a funciones criptográficas encontramos a nuestra disposición el popular sistema criptográfico RSA, con las capacidades de generación del par de claves publica/privada precisadas para el cifrado y firma de información, así como en las operaciones opuestas de conversión a texto claro y verificación de datos firmados; además de las funciones que permiten realizar precisamente todas estas tareas: cifrado, descifrado, firma, verificación de firma, y también la capacidad de verificar una clave. De hecho, siempre deberíamos de verificar la validez de una clave pública antes de su uso en el cifrado de los datos que queramos enviar al destinatario propietario de la misma, por ejemplo.

Si bien lo anterior es el plato fuerte en cuanto a las funciones disponibles bajo el módulo Crypto, también encontraremos la función HMAC que permite crear un código de autenticación de mensaje o, dicho de otro modo, una función Hash con esteroides en las que se utilizará el sistema de Hash que le indiquemos en combinación con una clave de nuestra cosecha. Precisamente para generar esa clave adicional de la función HMAC (o 'salt'), Xojo proporciona la función GenerateRandomBytes y cuya finalidad no puede ser más descriptiva. De hecho, el único parámetro de entrada no es otro sino un entero mediante el cual indicaremos el tamaño de salida, mientras que el producto será lo que en Xojo se denomina un MemoryBlock y que no es más que un buffer de memoria mediante el que podemos trabajar con los datos en bruto, sin estar envueltos bajo una estructura determinada (por supuesto, en Xojo encontraremos múltiples métodos de clase para convertir desde y hacia MemoryBlocks los datos correspondientes a las estructuras internas de dichas clases, como pueda ser el texto). Ahora bien, en su estado actual Xojo no expone muchos otros esquemas y algoritmos presentes en la librería Crypto++ 5.6.2, cosa aparte es que internamente pueda utilizar alguno de ellos. Quizá una de las ausencias más notables sea el esquema de criptografía de curva elíptica. Quizá es cuestión de tiempo que la veamos implementada en Xojo, junto con algunas otras ausencias notables. Aun así, con lo disponible cualquier usuario puede encontrar la respuesta a las principales necesidades en cuanto al cifrado y verificación de datos, así como en el típico almacenamiento y posterior verificación en las contraseñas u otra información de carácter sensible, especialmente cuando se utiliza Xojo Web o Xojo Pro para la creación de aplicaciones con despliegue web, o incluso Xojo Pro en la creación de aplicaciones de servidor autónomas donde la seguridad en el intercambio de la información sea un requerimiento fundamental. RSA en la práctica ¿Y cuán sencillo resulta aplicar todo lo anterior? Pues lo cierto es que sorprendentemente fácil, tanto por el diseño de las propias funciones como por el lenguaje Xojo en general. Por ejemplo, la creación del par de claves Pública/Privada que supone el punto de partida para utilizar el resto de funciones RSA es tan simple como utilizar el siguiente código, y del que estoy convencido que podrás entender perfectamente incluso en el caso de que esta sea tu primera exposición al lenguaje de programación Xojo.

Crypto.RSAGenerateKeyPair ( Bits As Integer, ByRef PrivateKey As String, ByRef PublicKey As String ) As Boolean En el parámetro Bits pasaremos como número entero la longitud de la clave, donde los valores típicos suelen ser 1.024 o 2.048. Sobre el resto, se utilizan dos parámetros de tipo String (cadena) y que serán los responsables de contener tanto la clave pública como la privada. Aquí, se utiliza la partícula 'ByRef' de Xojo para indicar que el parámetro se pasará como referencia y no como valor (es decir, como copia), de modo que se pueda modificar desde dentro de la función el contenido del objeto apuntado por la variable. Por último, la función devolverá un booleano donde se indicará mediante el valor 'True' que se ha podido realizar la operación con éxito o 'False' en caso contrario. Por tanto, un fragmento de código que nos permitirá crear ambas claves y cifrar a continuación un mensaje determinado sería el siguiente: Dim clavePrivada As String Dim clavePublica As String If Crypto.RSAGenerateKeyPair( 1024, clavePrivada, clavePublica ) Then Dim buffer As New MemoryBlock(15) buffer.StringValue(0, 15) = "Mensaje cifrado" Dim cifrado As MemoryBlock = Crypto.RSAEncrypt( buffer, clavePublica ) if cifrado nil then

MsgBox cifrado.StringValue(0,15)

dim descifrado as MemoryBlock = Crypto.RSADecrypt(cifrado, clavePrivada)

MsgBox descifrado.StringValue(0,15)

End If End If

Una vez cifrado, sólo es necesario utilizar a continuación la clave privada para volver a convertirlo en texto claro. Ahora bien, una particularidad de trabajar con bloques de memoria es que desaparece toda la información de codificación asociada con el texto (por ejemplo UTF-8), de modo que es preciso tenerlo en cuenta a la hora de volver a recuperar dicha información otra vez desde un bloque de memoria que hayamos descifrado. Acceso a Llaveros También hay que tener en cuenta que si bien el módulo Crypto incluye todas las funciones necesarias para cifrar, firmar o generar huellas digitales de nuestra información, depende de nosotros poner a buen recaudo las claves privadas que generemos. Existen muchas formas de hacerlo, y de hecho no debería de suponer ningún problema mediante las clases incluidas en el framework de Xojo. Ahora bien, los usuarios de OS X lo tienen aun un poco más sencillo gracias a que Xojo incluye soporte para la característica Acceso a Llaveros (Keychain) mediante la que se facilita sobremanera el guardado y recuperación de contraseñas utilizadas por las aplicaciones.

Qué son y para qué sirven los hash?: funciones de resumen y firmas digitales

Los hash o funciones de resumen son algoritmos que consiguen crear a partir de una entrada (ya sea un texto, una contraseña o un archivo, por ejemplo) una salida alfanumérica de longitud normalmente fija que representa un resumen de toda la información que se le ha dado (es decir, a partir de los datos de la entrada crea una cadena que solo puede volverse a crear con esos mismos datos). Estas funciones no tienen el mismo propósito que la criptografía simétrica y asimétrica, tiene varios cometidos, entre ellos está asegurar que no se ha modificado un archivo en una transmisión, hacer ilegible una contraseña o firmar digitalmente un documento

Características de los hash En definitiva las funciones hash se encargan de representar de forma compacta un archivo o conjunto de datos que normalmente es de mayor tamaño que el hash independientemente del propósito de su uso. Este sistema de criptografía usa algoritmos que aseguran que con la respuesta (o hash) nunca se podrá saber cuales han sido los datos insertados, lo que indica que es una función unidireccional. Sabiendo que se puede generar cualquier resumen a partir de cualquier dato nos podemos preguntar si se podrían repetir estos resúmenes (hash) y la respuesta es que teóricamente si, podría haber colisiones, ya que no es fácil tener una función hash perfecta (que consiga que no se repita la respuesta), pero esto no supone un problema, ya que si se consiguieran (con un buen algoritmo) doshash iguales los contenidos serían totalmente distintos. Ejemplos y formas de uso Las funciones hash son muy usadas, una de las utilidades que tiene es proteger la confidencialidad de una contraseña, ya que podría estar en texto plano y ser accesible por cualquiera y aún así no poder ser capaces de deducirla. En este caso, para saber si una contraseña que está guardada, por ejemplo, en una base de datos es igual a la que hemos introducido no se descifra el hash (ya que debería de ser imposible hacerlo) sino que se aplicará la misma función de resumen a la contraseña que especificamos y se comparará el resultado con el que tenemos guardado (como se hace con las contraseñas de los sistemas Linux). Pongamos un ejemplo, la función hash MD5 es una de estas funciones de resumen y la usaremos para resumir el siguiente texto: Genbeta Dev

Y aplicaré la función de resumen con el comando especifico que tienen la mayoría de sistemas basados en Linux (md5sum): pedro@ubuntu:~$ md5sum Genbeta Dev b71dada304875838f0263e3ae50c2c49 Por lo que la última línea es la del hash, que podéis comprobar en un terminal, en una herramienta online o con una aplicación con este fin, aunque se puede aplicar en muchos lenguajes de programación que lo implementan (no solo esta función, sino también otros tipos como el SHA que puede admitir distinta longitud). Asegurar la integridad de la información Otro uso que tiene esta función es la de garantizar la integridad de los datos y es algo que habréis visto muchas veces, por ejemplo en algunas webs que proporcionan descargas de archivos grandes, por ejemplos software, dando junto a su vez el resumen del archivo y la función usada. Por poner un ejemplo en la página de descarga de Virtual Box podemos encontrar esta página con todos los resúmenes de las descargas disponibles con los que podemos comprobar que el archivo se ha descargado correctamente y que nadie ha modificado su contenido durante la transmisión. Para poner en práctica este uso cogeré esta imagen de HTML5 y le aplicaré una función de resumen con el algoritmo MD5.

Y el resultado de hacer el resumen es el siguiente, usando otra vez la función presente en sistemas Linux (md5sum). pedro@ubuntu:~$ md5sum HTML5.png cc617bf6a1ec75373af6696873fccef1 HTML5.png Este es el método para saber que un documento está integro tras su recepción, por eso se usa para comprobar que un archivo se a descargado correctamente o para comprobar que datos como un pequeño texto sigue siendo el mismo tras su emisión. Firma digital

Firmar un documento no es algo novedoso, pero la firma digital si lo es un poco más y nos ayuda a verificar la identidad del emisor de un mensaje (así nos podemos asegurar que nuestro jefe nos manda un archivo concreto y no es el vecino que nos gasta una broma). El método más simple de firma digital consiste en crear un hash de la información enviada y cifrarlo con nuestra cave privada (de nuestro par de claves de la criptografía asimétrica) para que cualquiera con nuestra clave pública pueda ver el hash real y verificar que el contenido del archivo es el que hemos mandado nosotros. Me voy a adelantar al próximo capítulo sobre criptografía y hablaré un poquito de GnuPG (GPG) que es una herramienta de cifrado que nos permite firmar documentos, en este caso lo haré con una firma en texto plano (es un sistema menos seguro pero veremos que es lo que hace). Lo que voy a hacer es firmar la imagen que hemos usado antes (la de HTML5) con el siguiente comando en una terminal de Linux (para otras plataformas hay otras soluciones muy similares o incluso idénticas): pedro@ubuntu:~$ gpg --clearsign HTML5.png Necesita una frase contraseña para desbloquear la clave secreta del usuario: "Pedro "

Gutiérrez

Puente

(Clave

pública)

clave DSA de 3072 bits, ID 783F3E6D, creada el 2012-12-11 Automáticamente a partir del archivo HTML5.png nos genera el archivo HTML5.png.asc que si lo abrimos con un visor de texto vemos el contenido de la imagen (un conjunto de caracteres sin sentido) y al final del archivo el siguiente texto (que contiene el hash cifrado): -----BEGIN PGP SIGNATURE----Version: GnuPG v1.4.11 (GNU/Linux) iF4EAREIAAYFAlD0vH0ACgkQJQ5Gcng/Pm1gDgD+PnXZfni9n90duv2ir0hdnWdp 1bpBHGzCNWxN8q5I8CoA/RsdMeMxY9kwOx/y8jnxQYDjWFiBRThiE7GSxTtvXUPf =PwS6 -----END PGP SIGNATURE----Resumen

Junto con este artículo sobre los hash tenemos el que habla sobre los tipos de criptografía (simétrica y asimétrica) que son la base para comprender el siguiente y último de la serie sobre criptografía, donde pondremos en práctica estos conceptos junto a GPG.

¿Qué es y como surge la criptografía?: un repaso por su historia

La criptografía es una necesidad derivada de realizar comunicaciones por escrito (en su origen)creada

para

preservar

la

privacidad de

la

información

que

se

transmite, garantizando que una persona que no esté autorizada no pueda leer el contenido del mensaje. En la historia hemos tenido multitud de ejemplos de formas de encriptar mensajes como los métodos espartanos de hace 2.500 años, el cifrado de Polybios (de los griegos) o el cifrador del César (de los romanos), y sin olvidarnos de la máquina de encriptación más famosa de la historia: la máquina Enigma.

Historia de la criptografía En este artículo voy a tratar solamente de la historia de la criptografía y pondré unos ejemplos prácticos, posteriormente me adentraré en los distintos tipos de criptografía moderna y posteriormente su uso.

La escítala espartana (siglo V a. C.)

Los primeros mensajes cifrados que conocemos datan del siglo V antes de Cristo, de procedencia espartana, que ponían en práctica un método simple y rudimentario que consistía en coger una vara (llamada escítala), se le enroscaba una cinta de cuero o papiro y posteriormente se escribía de forma longitudinal (como en la imagen). Y por último se desenrollaba la cinta, con un puñado de letras sin sentido y se mandaba a través

del seur mensajero

de

turno

al

trote.

Supuestamente solo se podía desencriptar la información con una vara del mismo diámetro que la original sobre la que se escribió (obviamente si te pones a intentar cuadrar las letras acabas sacando algo en claro, pero en la época no se sabía demasiado leer, tampoco el idioma origen y mucho menos tenían la cultura general necesaria para pensar que la información estaba encriptada).

Uso El diámetro de la escítala es la clave de este método de encriptación (o simplemente cada cuantos caracteres empieza una vuelta). En el ejemplo encriptaremos la siguiente entrada de texto: Genbeta Dev – Historia de la criptografía – Método usado por los espartanos Y como clave o diámetro de la escítala (n) tomaremos el número 7, es decir, en cada vuelta

de

la

cinta

enroscada

en

el

la

vara

pondremos

7

caracteres.

El resultado es el siguiente: G tMose-doé pn egtpabH rooreiladrttsafo aat í ln ocauooDrr ssseii-a vap de Podéis poner la técnica en marcha con este ejemplo que he realizado y el código JavaScript es el siguiente: function escitala(txt,n){ //Convertimos "n" en entero var n=Math.floor(Number(n)) //"e" nos indica si entra justo en las filas var e=(txt.length%n>0?1:0) //Calculamos el número de filas resultantes var lin=Math.floor((txt.length/n)+e)

//"r" contiene la respuesta var r='' //Añadimos el carácter a la respuesta for(var a=0;a firmar.txt pedro@ubuntu:~/gpg$

gpg

-u

C4A9EA7A

--output

firmar.txt.gpg

--sign

firmar.txt Necesita una frase contraseña para desbloquear la clave secreta del

usuario:

"Pedro

Gutiérrez

(Manual

GPG

-

Genbeta

Dev)

" clave DSA de 2048 bits, ID 18384645, creada el 2013-01-23

Y ahora para asegurarse la confidencialidad del documento (ahora que esta firmado por nosotros) deberíamos de cifrarlo con la clave pública del destinatario.

Verificar y descifrar un archivo firmado

Cualquiera con la clave pública asociada a la que ha firmado el documento puede leerlo, de la misma forma que desciframos un archivo (gpg -d [Archivo]) o verificándolo únicamente con el comandogpg --verify [Archivo]. pedro@ubuntu:~/gpg$ gpg --verify firmar.txt.gpg gpg: Firmado el mié 23 ene 2013 05:25:18 CET usando clave DSA ID 18384645 gpg:

Firma

correcta

de

«Pedro

Gutiérrez

(Manual

GPG

-

Genbeta

Dev)

»

Y el resultado es la información del remitente, que podéis comprobar vosotros con este archivo y con la clave pública de los pasos anteriores.

Resumen GPG es una herramienta de cifrado muy potente y fácil de usar, que en principio, a la mayoría no nos hace falta, pero puede que se nos presente la necesidad de enviar algo por medio inseguros (porque no haya más remedio), haciéndolo de esta forma podremos hacerlo sin miedo ha que lean el contenido del archivo o nos den el cambiazo. Este es un tema bastante extenso y si no lo acabas de entender puede ser un lío, pero para preguntar están los comentarios.

http://www.genbetadev.com/