Los tipos de cifrado de disco en sistemas GNU/Linux pueden ser a nivel de bloque o a nivel de sistema de ficheros.
También llamado “cifrado del sistema de archivos apilados” o bien simplemente “cifrado de archivos / carpetas”, es una forma de cifrado de disco en el que los archivos o directorios son cifrados por el propio sistema de ficheros. Se implementan como una capa que se superpone en la parte superior de un sistema de archivos existente, haciendo que todos los archivos escritos a una carpeta habilitada para cifrarlos se cifren sobre la marcha antes de que el sistema de archivos subyacente los grabe en el disco, y se descifran cuando el sistema de archivos los lee desde el disco.
De esta manera, los archivos se almacenan en el sistema de archivos anfitrión en forma cifrada (lo que significa que sus contenidos y, por lo general, también sus nombres de archivo/carpeta, se sustituyen por datos aleatorios de más o menos la misma longitud), pero aparte siguen existiendo en ese sistema de archivos como lo harían sin cifrar, a modo de archivos normales / enlaces simbólicos / enlaces duros / etc.
La forma en que se implementa consiste en que para desbloquear la carpeta donde se almacenan los archivos cifrados en bruto en el sistema de archivos anfitrión («directorio inferior»), ésta debe montarse ( utilizando un pseudo sistema de archivos apilados especial) sobre sí misma u, opcionalmente, en una ubicación diferente («directorio superior» ), donde los mismos archivos aparecen entonces en forma legible —hasta que se desmonta de nuevo o se apaga el sistema—. Ejemplos de este tipo de ficheros sería eCryptfs y EncFS.
Los métodos de cifrado de dispositivo de bloque, por el contrario, operan como una capa debajo del sistema de archivos y se aseguran que todo lo escrito en un determinado dispositivo de bloques quede cifrado. Esto significa que mientras el dispositivo de bloque no está en línea, todo su contenido se parece a una amalgama de datos aleatorios, y no hay forma de determinar qué tipo de sistema de archivos y qué datos contiene. El acceso a los datos ocurre, de nuevo, mediante el montaje del contenedor protegido (en este caso el dispositivo de bloque) a una ubicación arbitraria con un método especial.
Cifrar una partición de un disco duro o cualquier otro dispositivo de bloques (disco USB, memoria flash, tarjeta SD, etc) es algo muy simple bajo sistemas Linux. No es obligatorio utilizar la extensión LUKS para cifrar discos en Linux, pero es recomendable debido a las ventajas de estandarización y seguridad que provee. Por ejemplo LUKS puede gestionar múltiples contraseñas, que pueden ser revocadas efectivamente y las protege contra ataques de diccionario con PBKDF2. Unos ejemplos de este tipo de cifrado serían Loop-AES , TrueCrypt y dm-crypt.
LUKS: Especificación de cifrado de disco estándar que no sólo facilita la compatibilidad y la interoperatividad entre los diferentes programas de cifrado que lo utilicen, sino que también garantiza que todas ellas implementen gestión de contraseñas en un lugar seguro y de manera documentada. La implementación en GNU/Linux se encuentra como añadido en cryptsetup, utilizando dm-crypt como la interfaz de cifrado de disco.
dm-crypt: infraestructura del kernel de Linux (> 2.6) que provee cifrado transparente de dispositivos de bloque, ofrece una capa de abstracción (ver). Las escrituras a este dispositivo serán cifradas y las lecturas descifradas. Debido a esa capa de abstracción que ofrece se podrá montar un sistema de archivos en el mismo de la manera habitual, pero no se podrán acceder los datos sin la clave.
cryptsetup: Herramienta que facilita el uso de dm-crypt, eliminando las llamadas directas a dmsetup.
El funcionamiento tradicional de las herramientas de cifrado era simple y podríamos asemejarlo a un archivo ZIP cifrado: El usuario introduce una contraseña y el programa utiliza esa contraseña para cifrar los datos. Esa sencillez, sin embargo, tiene varios inconvenientes implícitos:
Las contraseñas suelen ser demasiado cortas para ser seguras.
Las contraseñas suelen basarse en palabras existentes, por lo que son susceptibles a ataques de diccionario. La suma de ambos inconvenientes suele llevar a contraseñas de baja entropía, que provoca que queden muy lejos de la entropía necesaria para contraseñas de 256 bits, por ejemplo, por no hablar de contraseñas más largas (512, 1024 o 2048 bits).
Si alguien descubre la clave, o si tememos que eso haya ocurrido, la única forma de mantener los datos seguros incluso aunque sospechemos que los atacantes no han tenido acceso a ellos es descifrar todos los datos, elegir una nueva clave y volver a cifrar con dicha clave, lo cual puede suponer un tiempo no trivial además de un almacenamiento en claro en otro lugar que luego deberá ser borrado de forma segura. Vamos, un auténtico engorro que, conociendo al señor Murphy, nos ocurrirá en el peor momento posible.
Las implicaciones de ese funcionamiento tradicional eran claras: Dado que la capacidad de ataque por fuerza bruta crece mucho más rápidamente que la capacidad de los seres humanos para recordar contraseñas cada vez más largas y complejas, era necesario establecer otros mecanismos. Esos mecanismos son, por un lado, el establecimiento de un doble nivel de clave, y por otro, el almacenamiento seguro de la clave principal.
Doble nivel de clave.
En lugar de utilizar la clave suministrada por el usuario para cifrar los datos, lo que se hace es generar una clave maestra del tamaño deseado, criptográficamente segura, y almacenarla cifrada con la clave del usuario. Cuando se quiere acceder a los datos cifrados, el sistema solicita al usuario su contraseña, con ella y la clave maestra cifrada inicializa un sistema de protección y con éste accede a los datos. Como medida de precaución añadida para evitar ataques de diccionario, se utiliza un sistema que sea costoso calcular para esa inicialización inicial, de modo que el tiempo para un único intento sea aceptable pero para un ataque continuado no, y se complementa con el uso de un valor aleatorio añadido (salt) para evitar ataques de diccionario precalculado. Este sistema tiene además la ventaja de que la clave maestra no está nunca almacenada en claro en la memoria, por lo que tampoco es susceptible a ataques de congelación de memoria.
Almacenamiento seguro de la clave principal.
Teóricamente el mecanismo de doble nivel sería suficiente, pero como suele ocurrir teoría y práctica no siempre coinciden. Una de las características de los discos duros modernos es su capacidad para remapear sectores defectuosos de forma transparente, de manera que si el disco encuentra que un sector da problemas pero todavía tiene algún sector de reserva libre, “da el cambiazo” de forma que de cara al exterior todo va igual de bien y la vida del disco se prolonga. Nosotros ni nos damos cuenta del hecho y el tiempo medio entre fallos del fabricante aumenta, de modo que puedan presumir de fiabilidad.
Este comportamiento, interesante de cara a la supervivencia de los datos almacenados, tiene su contrapartida en el caso del cifrado: Si tenemos la mala suerte de que el sector que falla es el que contiene la clave maestra cifrada, nos va a quedar en disco una copia de dicha clave maestra cifrada con la contraseña que tuviésemos en ese momento, en un lugar inaccesible para nosotros pero no para las herramientas de análisis forense. Para evitar esto lo que se hace es no almacenar la clave maestra cifrada en un sector concreto, sino particionarla en varios trozos de forma que todos sean necesarios para recuperar la clave (por ejemplo, mediante un XOR) y almacenando cada trozo en un lugar diferente. De esta manera, incluso aunque tengamos la mala suerte de que el disco duro nos la juegue con los sectores defectuosos, tendría que ocurrir no sólo que todos los sectores que contienen trozos de la clave fuesen sustituidos, sino que además no se hubiese producido ningún cambio de contraseña entre el fallo del primer sector y el del último, lo que provocaría que los trozos guardados por el disco duro no se complementasen y por tanto no se pudiese recuperar la clave.
La suma de ambos mecanismos es lo que se conoce como esquema TKS1 y es la base del funcionamiento de LUKS: Una clave principal almacenada de forma segura, con la que se cifran los datos, y una o varias contraseñas que los usuarios utilizan para acceder a la clave principal y desbloquear el acceso a los datos.
En el próximo episodio veremos una implementación real de todo este esquema teórico y cómo se traduce en unos pocos cambios en un sistema que, por lo demás, mantiene las características habituales en los sistemas Linux.
Crear el volumen lógico con cryptsetup indicando el algoritmo, tipo de hash para almacenar la contraseña y tamaño de la clave (adaptarlo a las necesidades).
cryptsetup -c twofish -h sha512 -y -s 256 luksFormat /dev/sda3 WARNING! ======== Esto sobrescribirá los datos en /dev/sda3 de forma irrevocable. Are you sure? (Type uppercase yes): YES Introduzca la frase contraseña: Verifique la frase contraseña:
Abre el volumen Luks y mapea el volumen físico (/dev/sda3) con el virtual cifrado (/dev/mapper/cifrada).
cryptsetup luksOpen /dev/sda3 cifrada Introduzca la frase contraseña de /dev/sda3:
Crear el sistema de archivos XFS (utilizando el mapeo creado anteriormente).
mkfs.xfs /dev/mapper/cifrada
Creamos el punto de montaje /media/sda3 y montamos la partición.
mkdir /media/sda3 mount /dev/mapper/cifrada /media/sda3/
Cierra el volumen LUKS (Elimina el mapeo).
cryptsetup luksClose /dev/mapper/cifrada
NOTA: Una vez esté creado el cifrado del disco, dependiendo del gestor de ficheros / escritorio utilizado se podrá montar y desmontar (mapeado incluido) la partición a golpe de ratón.
Enlaces de interés: http://www.kriptopolis.com/cifrado-disco-linux-1