
Sencilla herramienta de esteganografía de imágenes en C++ para cifrar y ocultar archivos dentro de imágenes usando codificación de bits menos significativos.
Herramienta simple de Cifrado y Esteganografía que utiliza cifrado protegido por contraseña para asegurar el contenido de un archivo, y luego lo incrusta en los datos de píxeles de una imagen utilizando codificación de bit menos significativo. Para sistemas Linux, macOS y Windows.
$ ./steganography encode -i data/orig.png -e data/jekyll_and_hyde.zip -o output.png
Password: 1234
* Image size: 640x426 pixels
* Encoding level: Low (Default)
* Max embed size: 132.38 KiB
* Embed size: 61.77 KiB
* Encrypted embed size: 61.78 KiB
* Generated CRC32 checksum
* Generated encryption key with PBKDF2-HMAC-SHA-256 (20000 rounds)
* Encrypted embed with AES-256-CBC
* Embedded jekyll_and_hyde.zip into image
* Sucessfully wrote to output.png
Imagen original:

Imagen con ZIP incrustado que contiene todo el contenido del libro "Dr Jekyll y Mr Hyde":

$ ./steganography decode -i output.png -o "out - jekyll_and_hyde.zip"
Password: 1234
* Image size: 640x426 pixels
* Generated decryption key with PBKDF2-HMAC-SHA-256 (20000 rounds)
* Sucessfully decrypted header
* File signatures match
* Detected embed jekyll_and_hyde.zip
* Encoding level: Low (Default)
* Encrypted embed size: 61.78 KiB
* Successfully decrypted the embed
* Decrypted embed size: 61.77 KiB
* CRC32 checksum matches
* Successfully wrote to out - jekyll_and_hyde.zip
$ mkdir build
$ cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ make -j 4
Usage: steganography [-h] {decode,encode}
Optional arguments:
-h, --help shows help message and exits
-v, --version prints version information and exits
Subcommands:
decode Decodes and extracts an embed-file from an image
encode Encodes an embed-file into an image
Usage: encode [-h] --input VAR --output VAR --embed VAR [--passwd VAR]
Encodes an embed-file into an image
Optional arguments:
-h, --help shows help message and exits
-v, --version prints version information and exits
-i, --input specify the input image. [required]
-o, --output specify the output image. [required]
-e, --embed specify the file to embed. [required]
-p, --passwd specify the encryption password.
Usage: decode [-h] --input VAR [--output VAR] [--passwd VAR]
Decodes and extracts an embed-file from an image
Optional arguments:
-h, --help shows help message and exits
-v, --version prints version information and exits
-i, --input specify the input image. [required]
-o, --output specify the output file. [default: ""]
-p, --passwd specify the encryption password.
El programa opera generando primero aleatoriamente una Sal de Contraseña de 128 bits y un Vector de Inicialización AES de 128 bits leyendo datos binarios de /dev/urandom. Luego usa esa Sal de Contraseña como parámetro para generar una clave de cifrado, utilizando PBKDF2-HMAC-SHA-256 sobre una cadena introducida por el usuario. A continuación, se calcula un hash CRC32 del archivo a incrustar, y se almacena en la cabecera para actuar como suma de verificación de la validez de los datos. Luego rellena los datos binarios del archivo a incrustar usando el algoritmo PKCS #7, seguido de cifrar tanto la cabecera como los datos rellenados, con AES-256 en Modo CBC, utilizando el Vector de Inicialización previamente generado. Ahora los datos se codifican realmente dentro de la imagen seleccionando primero un desplazamiento aleatorio, y luego recorriendo cada bit de datos y almacenándolo dentro de los datos de píxeles de la imagen real, lo que logra estableciendo el Bit Menos Significativo de cada byte de canal de cada píxel.
El proceso de decodificación funciona exactamente igual que el proceso de codificación descrito anteriormente, pero en orden inverso. La única diferencia es que para la decodificación, después de que el programa intente extraer y descifrar los datos, compara parte de la información en la sección de cabecera en un intento de validar el proceso de extracción. Los campos de la cabecera que se comparan son: La firma de archivo de 4 bytes personalizada de este programa, y el hash CRC32 de los datos descifrados. Si alguno de estos campos no coincide con sus valores correctos, el proceso de descifrado fallará. Esto solo debería ocurrir si el archivo que se intenta descifrar no contiene realmente una incrustación, si la contraseña introducida es incorrecta, o si el archivo de imagen se ha corrompido de alguna manera.
Si bien la detección de datos incrustados en una imagen es una tarea trivial, teóricamente no hay forma de saber que fue este programa el que lo hizo, y teóricamente no debería haber una forma conocida de descifrar los datos sin conocer la contraseña, sin invertir millones de años en el proceso.
No use este programa para cifrar y ocultar datos importantes que desee mantener alejados de miradas indiscretas. Esto es solo un programa simple de prueba de concepto que hice por diversión. No soy criptógrafo. Solo soy un aficionado, úselo bajo su propio riesgo.
Este software está licenciado bajo MIT. Copyright © 2022 Zach Collins