Negación creíble con LUKS


Publicado:   |   Прочесть по-русски   |   Read in English   |   Más posts sobre LUKS security software

En este artículo os contaré como crear un contenedor oculto con ayuda de medios regulares de sistema operativa Linux (LUKS y cryptsetup). Unas funciones ordinarias de LUKS (tales como usar un encabezado externo y poner datos en sí con desplazamiento) permiten al usuario acceder a datos ocultos dentro de contenedor existente y al mismo tiempo negar su existencia.

UPD[31/05/2014]: Este post estaba listo hace más de un mes, y aquello tiempo ni siquiera podía imaginar tan extraña muerte súbita del TrueCrypt. Bueno, tal vez este proyecto no esta completamente muerto, a ver… Sin embargo, en el texto siguiente dejo referencias a TrueCrypt como es.

Qué es «negación creíble»?

Podéis encontrar una definición muy larga y detallada del término en Wikipedia: http://en.wikipedia.org/wiki/Plausible_deniability. Por desgracia, no hay tal articulo en español. En pocas palabras eso significa que podéis hacer o tener algo y nadie puede sospecharlo y demostrarlo (por supuesto, si no lo admitís). Y después podéis negar hacerlo o tenerlo si alguien quiera os acusar (lo repito: porque nadie puede demostrarlo). Por ejemplo, si un chico da un puntapié a su hermano menor mientras nadie lo ve, y su hermano va buscar a justicia a su padres, entonces ¿qué pasará?

Pues... Nada. Porque este chico negará lo que ha dado un puntapié a su hermano y los padres no podrán atraparlo este tiempo (primero, no hay testigos, segundo, el hermano puede jugar a su juego sucio). Entonces castigarán a nadie. O, que es peor, castigarán a ambos, por si acaso. Eso es un ejemplo de negación creíble para el caso de este chico propenso a la violencia. Pero nosotros somos, sin duda, personas bien criadas y usaremos contenedores ocultos sólo para proteger los datos nuestros de malos tipos. Quien es bueno y quien es malo en este caso es la pregunta difícil, pero… ¡Al grano!

La idea general de realización

Supongamos que queremos guardar algunos datos valiosos entre un archivo cifrado. Generalmente usamos algún programa de criptografía, que hace la tarea para nosotros. Tal vez queramos trabajar con el archivo como con el disco virtual, y eso disminuye considerablemente el número de candidatos. Pero la propiedad esencial de tales programas es lo que operan con el archivo como con uno gran trozo de datos cifrados. Es decir el usuario tiene sólo una contraseña (tal vez unas contraseñas «de sobra» por si acaso) que sirve para descifrar todos los datos entre el contenedor. Eso significa que en este caso hay sólo un punto débil: la contraseña del contenedor. No quiero mencionar lo que la contraseña debe ser segura criptográficamente, ya que es una obviedad. Quiero decir que si el usuario de la programa tiene que revelar su contraseña (p.ej. si está presionado), todos los datos habrán revelado también. Y pienso que eso es triste y mal…

Pues, sin embargo, hay una esperanza. :) Por ejemplo, existe tan programa como TrueCrypt, que está bastante lista. El usuario puede crear dos contenedores entre uno archivo: lo primero es el falso con algunos archivos indebidos, pero relativamente seguros, y el segundo es el real, con datos, los que nadie deberá encontrar en ningún caso. Así pues TrueCrypt pide del usuario dos contraseñas diferentes, cuando el usuario quiere crear tal «doble» contenedor. Más tarde el usuario introduce sólo una contraseña para abrir el parte «real» de contenedor y trabaja con esta parte. Cuando y si bajo de presión de las circunstancias externas el usuario tiene que mostrar el contenido de su disco cifrado a terceros, él simplemente introduce la segunda contraseña, y TrueCrypt abre el parte falso del contenedor. Se debe subrayar (ya que es muy importante), que no hay ninguna posibilidad para probar la existencia del parte «oculto» si investigador no sabe la contraseña apropiada.

Y ahora vamos a ver, como funciona… En realidad todo es muy sencillo. Software divide el archivo por dos (hablando en general, desiguales) partes. La primera parte, que puede ser algo pequeño, contiene datos falsos; la segunda es para datos reales. Entonces la programa debe mantener dos encabezados (configuraciones) diferentes para dos partes diferentes y elegir, que parte descifrar según la contraseña dado por el usuario. Y eso no está la parte más fácil del trabajo. Porque «oficialmente» deben poder ver sólo una configuración falsa. Si hay un encabezado estándar en el contenedor, eso debe ser encabezado falso. Si los parámetros para descifrar están en el archivo de configuración, tales parámetros deben permitir descifrar sólo la parte falsa. Ni idea de la parte real no debe aparecer después descifrar el parte falsa. Las partes deben ser completamente independientes. Además, mientras la parte falsa está abierta, software debe mostrar toda capacidad del disco cifrado, aunque la capacidad real de la parte falsa es mucho menor.

Entonces, ¿qué pasa con LUKS?

Hay buenas noticias y… Pues… Y mejores noticias.

Las buenas son lo que cryptsetup puede descifrar y montar volúmenes creados por TrueCrypt. Sin embargo sólo para leer, pero no importa. Porque son mejores noticias. Es decir podemos creer un contenedor «oculto» sólo por cryptsetup. Es más, ésta herramienta deja crear algún número de partes «ocultos». Por supuesto, en los límites razonables. Y aquí está como hacerlo.

Pero antes seguiremos,

GRANDE GORDA ESPANTOSA ¡¡¡ADVERTENCIA!!!

  • Todo lo que está escrito abajo puede ocasionar un daño irreparable a vuestros datos.
  • Usar la criptografía fuerte puede ser prohibido en vuestro país, entonces pueden encarcelaros no por la información real, sino sólo por el contenedor cifrado, lo que han encontrado en vuestro disco duro.
  • Criptografía puede proteger vuestros datos, pero no puede protegeros de tormentos. El contenedor oculto puede salvar vuestra información de valor, pero vosotros no podéis negar su existencia en caso de traición o denuncia.
  • Tíos interesados en vuestros datos cifrados puede ser no tan tontos como pensabais. Incluso si no puedan demostrar la existencia de la parte oculta en el contenedor, de seguro pueden quedaros en la celda con los criminales empedernidos, y en un par de días os recordaréis todas vuestras contraseñas a todas vuestros datos ocultos.
  • Si tenéis un(a) novio/a y/o parientes cercanos (así como amigos íntimos), entonces ellos también pueden hacerse los objetivos para presionarles. Y tal caso puede simplificar en gran medida vuestra tarea de recordar a todo, aunque lo que no sabíais.

Entonces pensad dos veces si vuestra información cuesta la vida vuestra o de vuestros seres queridos. Y haced la copia de seguridad de vuestros datos. Por si acaso.

Pues, bueno, estáis advertidos, entonces sigamos.

man cryptsetup puede contarnos sobre algunos parámetros de esta utilidad muy interesantes. Por ejemplo, a ver que es la --header opción:

--header <dispositivo o archivo donde está el encabezado de LUKS>
  Usar un dispositivo de metadatos o archivo independiente (separado) donde se encuentra el encabezado de LUKS. Esta opción permite guardar datos cifrados y el encabezado de LUKS en dispositivos diferentes.

Está bien. Esto significa lo que podemos tener un volumen lleno de basura aleatoria sin alguna signatura determinada. Descripción de esta opción contiene un poco más información, precauciones y advertencias, pero lo que es esencial es exacto eso. Y con todo eso os aconsejo con insistencia que leáis este manual.

Otra opción muy útil es --align-payload; esta permite colocar los datos reales por algún desplazamiento desde el principio del volumen:

--align-payload <numero de 512-byte sectores>
 

Alinear la carga útil al límite de numero de 512-byte sectores. Esta opción está pertinente a luksFormat.

Si no está especificado, para traer el alineación óptima cryptsetup prueba usar la información de topología que el núcleo facilita para dispositivos inferiores. Si no hay tal información (o el valor calculado es múltiplo de omisión), datos están alineados por omisión por el límite de 1MiB (es decir 2048 512-byte sectores).

En caso de encabezado de LUKS separado esta opción significa el desplazamiento en el dispositivo de datos. Vea también la opción --header.

Y eso es muy gracioso también, porque ahora somos libre de mover nuestros datos a algún parte del volumen. Ya caéis, ¿eh?

Resumiendo. Qué hay que hacer:

  1. Inicializar el volumen para cifrado: sobrescribirlo completamente con los datos aleatorios.
  2. Hacer un volumen cifrado «oficial» y guardar en ello algunos warez infectados, música pirateada, porn utilidades freeware útiles, grabaciones de tu grupo amateur de rock, pelis de amor etc., i.e. algún contenido por lo que te condenarán a cárcel no más que por dos años condicionalmente.
  3. Usando las opciones esotéricos de cryptsetup mencionadas antes, hacer el volumen oculto (dentro de el «oficial») y guardar su encabezado en un medio exterior. Allí puedes conservar datos realmente peligrosos (tales como tus fotos de guardería infantil o tus planes de conquistar el mundo).

¡Y eso es todo, chicos! No hay ninguna magia aquí. Evidentemente, es importante que no llenéis vuestro disco cifrado «oficial» con la basura hasta los topes, porque comparte el espacio con el disco oculto. Y, como he dicho antes, podéis, si quieréis, crear varios discos ocultos según la misma lógica.

Pues, bueno… Si todavía necesitáis más información, especialmente para vosotros aquí está

Guía paso a paso

¡Atención!

Comandos siguientes destruirán vuestros datos, si los ejecutáis sin pensar. Perjuicio será irreparable, porque tales utilidades como dd trabajan en nivel muy bajo (i.e. debajo del nivel de sistema de archivos). Entonces será imposible retrotraerlo o deshacerlo, aunque lo suspendisteis justo después de ese programa había iniciado.

No lo hagáis, si no podéis explicar claramente como cada paso se relaciona a vuestro objetivo. Y haced el backup. Ahora mismo.

Supongamos que tenemos algún disco duro con varias particiones. Deja que sea, por ejemplo, /dev/sdb. Y que /dev/sdb1 sea relativamente pequeña (8GB) partición asignada para cifrado. La dividamos como 5/3, donde 5GB parte será la parte «oficial» y 3GB parte será la parte oculta. Supongamos también que queremos guardar llave de almacenamiento secreto en nuestro disco duro en /etc/keys y encabezada del contenedor oculto en la memoria USB externa montada a /media/user/ExtUSBStick. Creo que sabéis como establecer permisos de vuestro archivo de claves, como configurar encfs/ecryptfs para mantener archivos secretos de forma segura en los dispositivos inseguros y lo que debéis que copiar llaves secretas reales y guardarlas en dos o tres cajas fuertes en ubicaciones diferentes.

Bueno, es suficiente refunfuñar. Vayamos a punto.

  1. Inicializad dispositivo /dev/sdb1:

    dd if=/dev/urandom of=/dev/sdb1 bs=16M
    
  2. Haced un llave para el volumen cifrado. La llave aleatoria de 512 bits (64 bytes) está más que suficiente:

    dd if=/dev/urandom bs=64 count=1 >/etc/keys/secret.key 2>/dev/null
    
  3. Cifrad el volumen con la llave nueva:

    cryptsetup luksFormat /dev/sdb1 /etc/keys/secret.key
    
  4. Abrid el dispositivo cifrado y configura mapping secretdata:

    cryptsetup luksOpen --key-file /etc/keys/secret.key /dev/sdb1 secretdata
    
  5. Cread un sistema de archivos en el volumen cifrado (e.g., btrfs):

    mkfs.btrfs -L SecretData /dev/mapper/secretdata
    
  6. … y montad la:

    mount /dev/mapper/secretdata /var/secretdata/
    
  7. Nos acordaremos de 5G límite, entonces ejecutad cuota para subvolumenes:

    btrfs quota enable /var/secretdata/
    
  8. Ya que se puede aplicar btrfs cuotas sólo a subvolumenes, creamos un subvolumen:

    brfs subvolume create /var/secretdata/workingvolume
    
  9. … y aplicamos la dicho cuota (fijaos lo que se puede montar btrfs subvolumenes como sistemas de archivos ordinarias, entonces tal vez en el futuro quisiereis montar este subvolumen en lugar de llena sistema de archivos):

    btrfs qgroup limit 5G /var/secretdata/workingvolume
    
  10. Llenadlo con algunos datos:

    debootstrap --variant=buildd testing /var/secretdata/workingvolume
    
  11. Eso es todo, ahora podemos olvidar a esta parte:

    umount /var/secretdata
    cryptsetup luksClose secretdata
    
  12. Ahora cread un archivo para encabezado y hinchalo con basura aleatoria:

    dd if=/dev/urandom of=/media/user/ExtUSBStick/hidden.head bs=4M count=1
    
  13. Y ahora es el mismo momento, donde empieza la magia real. (¿Qué? ¿He dicho, que no hay magia? He mentido.) Usaremos la misma llave, pero no entera, sólo una mitad (desplazamiento 32 bytes). Sin embargo, 256 bits de datos aleatorios son bastante para llave. Después separamos el encabezado y lo guardaremos en memoria USB externa. Y por fin decimos a cryptsetup que queremos desplacer nuestro contenedor oculto por 5GB (i.e. 10485760 512-byte bloques) desde el principio del volumen:

    cryptsetup --keyfile-offset 32 --header /media/user/ExtUSBStick/hidden.head \
    --align-payload 10485760 luksFormat /dev/sdb1 /etc/keys/secret.key
    
  14. Sí, todo es tan fácil. Ahora abrimos nuevo dispositivo cifrado:

    cryptsetup luksOpen --key-file /etc/keys/secret.key --keyfile-offset 32 \
    --header /media/user/ExtUSBStick/hidden.head /dev/sdb1 realsecretdata
    
  15. Haced alguna sistema de archivos que queréis:

    mkfs.btrfs /dev/mapper/realsecretdata
    

Y así sucesivamente…

Enlaces útiles

Para los que quieren saber más, aquí tenéis algunas fuentes informativas:

Y ahora, como dijo el autor de cryptsetup, «si insistís en dispararos en la pierna, podéis imaginar como hacerlo». ¡Suerte!