Algoritmos

Introducción a la esteganografía con imágenes en LSB

Introducción

La esteganografía es una técnica para ocultar mensajes en un canal encubierto. Hay muchas formas de hacerlo, y hoy veremos cómo es que se hace en imágenes. Sólo explicaremos la teoría, no haremos nada práctico por el momento.

Actualización: aquí un ejemplo.

Recordando cómo se compone una imagen

Una imagen tiene pixeles. Y cada pixel tiene un nivel de rojo, verde y azul. Dichos niveles van desde 0 hasta 255, y se les conoce como colores RGB.

  • El color blanco es 255, 255, 255
  • El negro es 0, 0, 0

Podemos combinar de cualquier forma estos colores

Bits y bytes

Por lo tanto, cada pixel puede alojar 3 bytes de información, uno por cada nivel de color. Recordemos que un byte son ocho bits, o sea, 8 ceros o unos.

Y el mayor número decimal que podemos representar con 8 bits (un byte) es 255, que en binario es 11111111.

Así que los niveles de los colores ocupan un byte. Si su valor es 0, el byte es 00000000. Si es 1, 00000001, y así.

LSB o bit menos significativo

Ya dijimos que 11111111 es 255, y 00000001 es 1. Ahora vamos a ver el bit más y menos significativo. El menos significativo (LSB) es el que, al cambiar su valor, no afecta mucho. Es el último bit de izquierda a derecha.

Pongamos el ejemplo de 255, que es 11111111:

Si cambio su último bit por un 0, entonces será 11111110. Al convertirlo a decimal, será 254, no es una gran diferencia.

MSB o bit más significativo

El MSB es el primer bit si ordenamos de izquierda a derecha. Siguiendo el ejemplo de 255, que es 11111111 vamos a cambiarlo.

Cambiamos 11111111 por 01111111. Al convertirlo en decimal, tenemos el número 127; es decir, de 255 pasó a 127. Eso sí fue un gran cambio.

Escondiendo un bit de información en el LSB

Ya vimos que no afecta mucho si cambiamos el LSB, pues sólo aumentará o disminuirá 1. Entonces descomponemos una cadena, la convertimos en bits y escondemos un bit por cada nivel de color.

Ejemplo

Escondamos la palabra “Ho”. El número o código ascii que le corresponde a cada letra es como se ve abajo:

  • H: 72
  • o: 111

Ahora vamos a convertir esos números a binario:

  • 72: 01001000
  • 111: 01101111

Supongamos que tenemos algunos pixeles de una imagen así como se ve abajo. El orden es R, G, B o Rojo, Verde, Azul. Sin alterar, se ven así:

  1. (80, 20, 55)
  2. (12, 20, 55)
  3. (80, 55, 55)
  4. (32, 20, 55)
  5. (80, 2, 200)
  6. (20, 152, 96)

Su representación binaria es esta:

  1. (01010000, 00010100, 00110111)
  2. (00001100, 00010100, 00110111)
  3. (01010000, 00110111, 00110111)
  4. (00100000, 00010100, 00110111)
  5. (01010000, 00000010, 11001000)
  6. (00010100, 10011000, 01100000)

Alterar bytes por cada bit

Ahora, por cada bit de la palabra “Ho” vamos a alterar un byte de un nivel de color los pixeles.

“Ho” en bits, es esto (el 72 y el 111 en binario):

01001000 01101111

Comenzamos con el primer bit (0), lo acomodamos en el valor R del primer pixel. El segundo bit (1) en el valor G del primer pixel, el tercero (0) en el valor B del primer pixel. Luego, el cuarto bit (0) en el valor R del segundo pixel y así sucesivamente.

Los pixeles, ya modificados y en binario, lucen así  como se ve abajo. Notar por favor que en el nivel B del tercer pixel comenzamos a escribir el primer bit de la letra “o”.

  1. (01010000, 00010101, 00110110)
  2. (00001100, 00010101, 00110110)
  3. (01010000, 00110110, 00110110)
  4. (00100001, 00010101, 00110110)
  5. (01010001, 00000011, 11001001)
  6. (00010101, 10011000, 01100000)

Los últimos dos niveles del sexto pixel los dejamos intactos, pues ya escondimos lo que era necesario. Ahora vamos a ver lo más interesante de esto.

Convertir de nuevo a decimal

Ya tenemos nuestros pixeles modificados, vamos a convertirlos a decimal. Se ven así:

  1. (80, 21, 55)
  2. (12, 21, 55)
  3. (80, 55, 55)
  4. (33, 21, 55)
  5. (81, 3, 201)
  6. (21, 152, 96)

Y los originales eran estos:

  1. (80, 20, 55)
  2. (12, 20, 55)
  3. (80, 55, 55)
  4. (32, 20, 55)
  5. (80, 2, 200)
  6. (20, 152, 96)

Viéndolo como números, claro que se ve la diferencia. Veamos ahora cómo se ven en colores.

Diferencia no notable al ojo humano

Tomemos el primer pixel. El original era 80, 20, 55. El modificado es 80, 21, 55. Aquí los colores:

Izquierda color original. Derecha color modificado (lo saqué de aquí). Al menos yo no veo alguna diferencia, y de hecho esta es una imagen grande. Recordemos que un pixel es mucho mucho más pequeño, así que… ¿quién notaría la diferencia?

Así podemos esconder información en cada pixel. Para recuperarla, hay que hacer el proceso inverso, con la diferencia de que cada que llevemos ocho bits tenemos que calcular su valor en decimal, y luego convertir ese decimal al carácter que le corresponde.

¿Es esto seguro?

Claro que lo es, pero no de este modo. Tenemos que aprender a no ser tan predecibles. Por ejemplo, modificar pixeles pero no en un orden, sino aleatoriamente. Rotar el texto antes de escribirlo, cosas de esas.

Es importante notar que también podemos (y lo recomiendo ampliamente) encriptar el texto antes de esconderlo. Así, aunque alguien descubra que hay texto ahí, no sabrá cuál es el mensaje original.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.
parzibyte

Programador freelancer listo para trabajar contigo. Aplicaciones web, móviles y de escritorio. PHP, Java, Go, Python, JavaScript, Kotlin y más :) https://parzibyte.me/blog/software-creado-por-parzibyte/

Ver comentarios

Entradas recientes

Creador de credenciales web – Aplicación gratuita

Hoy te voy a presentar un creador de credenciales que acabo de programar y que…

1 semana hace

Desplegar PWA creada con Vue 3, Vite y SQLite3 en Apache

Ya te enseñé cómo convertir una aplicación web de Vue 3 en una PWA. Al…

2 semanas hace

Arquitectura para wasm con Go, Vue 3, Pinia y Vite

En este artículo voy a documentar la arquitectura que yo utilizo al trabajar con WebAssembly…

2 semanas hace

Vue 3 y Vite: crear PWA (Progressive Web App)

En un artículo anterior te enseñé a crear un PWA. Al final, cualquier aplicación que…

2 semanas hace

Errores de Comlink y algunas soluciones

Al usar Comlink para trabajar con los workers usando JavaScript me han aparecido algunos errores…

2 semanas hace

Esperar promesa para inicializar Store de Pinia con Vue 3

En este artículo te voy a enseñar cómo usar un "top level await" esperando a…

2 semanas hace

Esta web usa cookies.