Pitón y esteganografía

No hace mucho tiempo, se llevó a cabo un piloto Hackathon para estudiantes en mi escuela . El tema de las tareas estaba relacionado con la seguridad de la información, incluido el cifrado de datos.



Una de las tareas más coloridas fue TASK-10: esteganografía .
Damos una definición.
La esteganografía es una forma de transmitir o almacenar información, teniendo en cuenta la confidencialidad del hecho mismo de dicha transferencia (almacenamiento).
En otras palabras, si la criptografía oculta la información en sí, entonces la esteganografía oculta el hecho de su transmisión.



Desafortunadamente, el equipo y yo no tuvimos tiempo para completar esta tarea a tiempo, y decidí completarla después del evento.

La solución más obvia en ese momento parecía ser:

  1. Convierta el texto cifrado en conjuntos de bits.
  2. Haz lo mismo con la imagen.
  3. Coloque el texto en un lugar aleatorio en la imagen y guárdelo como una imagen.

Aquí hay un pequeño código para convertir texto a conjuntos de bits y viceversa.

def text_to_binary(event): return [int(format(ord(elem),'b')) for elem in event] def binary_to_text(event): return [chr(int(str(elem),2)) for elem in event] 

Sin embargo, después de contarles a mis colegas más experimentados sobre mis pensamientos, me enviaron a enseñar material.
Debe comenzar con el hecho de que los bytes del archivo de imagen no se pueden editar directamente si no es bmp.

{% - codificador aleatorio%}
Después de leer un poco sobre los modelos de color, decidí abandonar la descomposición de la imagen a 1 y 0 a favor de las modificaciones de los píxeles en la paleta RGB. Para estas manipulaciones, elegí la biblioteca Pillow, aquí hay un buen artículo al respecto.

Entonces tenemos una imagen. La imagen tiene píxeles. Los píxeles se forman a partir de colores primarios: rojo, verde y azul.

Cada uno de los colores está codificado con un número del 0 al 255.



Y también tenemos caracteres ASCII que también están codificados.

Intentemos encriptar algo de texto en esta imagen.

Imagen:




Un poco de texto:
C facilita dispararse en el pie; C ++ lo hace más difícil, pero cuando lo haces, te vuela toda la pierna
Conecta las bibliotecas necesarias.

 from PIL import Image, ImageDraw from random import randint 

Luego declaramos la función y ponemos en ella todos los objetos que nos son útiles.

 def stega_encrypt(): keys = [] img = Image.open(input("path to image: ")) draw = ImageDraw.Draw(img) width = img.size[0] height = img.size[1] pix = img.load() f = open('keys.txt','w') 

Más interesante La tarea más importante es encontrar una forma de encriptar los mensajes. He propuesto este método :

  1. Tome un caracter, traduzca a un número ASCII
  2. Crea una tupla con coordenadas aleatorias
  3. Recolectamos sombras verdes y azules de un píxel en las coordenadas
  4. Reemplace el tono rojo con el número de carácter ASCII

 for elem in ([ord(elem) for elem in input("text here: ")]): key = (randint(1,width-10),randint(1,height-10)) g, b = pix[key][1:3] draw.point(key, (elem,g , b)) f.write(str(key)+'\n') 

Guardamos las llaves y la imagen.

 print('keys were written to the keys.txt file') img.save("newimage.png", "PNG") f.close() 

codigo

Intentamos ejecutar el script.

Como resultado, obtuvimos la misma imagen, pero en formato png y con algunos píxeles cambiados.



Ahora queda por descifrarlo de alguna manera.

¡Estamos escribiendo un guión para descifrar!

Conectamos todo lo que se necesita.

 from PIL import Image from re import findall 

Declaramos una función para descifrar, así como varios objetos.

 def stega_decrypt(): a = [] keys = [] img = Image.open(input("path to image: ")) pix = img.load() f = open(input('path to keys: '),'r') y = str([line.strip() for line in f]) 

Algoritmo de descifrado básico:

 for i in range(len(findall(r'\((\d+)\,',y))): keys.append((int(findall(r'\((\d+)\,',y)[i]),int(findall(r'\,\s(\d+)\)',y)[i]))) for key in keys: a.append(pix[tuple(key)][0]) return ''.join([chr(elem) for elem in a]) 

Estas expresiones regulares son necesarias para leer tuplas de un archivo de texto.

La última acción es mostrar un mensaje cifrado en la pantalla.

 print("you message: ", stega_decrypt()) 

codigo

Ahora trata de recibir nuestro mensaje.



Como se requiere para probar, ¡todo funciona!

La principal desventaja: la visibilidad de los píxeles muertos en la imagen en el caso del cifrado de una gran cantidad de caracteres. Sin embargo, este defecto está perfectamente corregido por alta resolución.

Referencias

Source: https://habr.com/ru/post/es413803/


All Articles