Python and steganography

Not so long ago, a pilot Hackathon for students was held at my school . The subject of tasks was related to information security, including data encryption.



One of the most colorful tasks was TASK-10: steganography .
We give a definition.
Steganography is a method of transmitting or storing information, taking into account that the very fact of such transmission (storage) is kept secret.
In other words, if cryptography hides the information itself, then steganography hides the fact of its transmission.



Unfortunately, the team and I did not have time to do this task on time, and I decided to fulfill it after the event.

The most obvious solution at the time seemed:

  1. Translate encrypted text into sets of bits.
  2. Do the same with the image.
  3. Place the text in a random place of the image and save it as a picture.

Here is a small code to convert text into sets of bits and back.

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] 

However, having told my experienced colleagues about my thoughts, I was sent to teach the materiel.
You need to start with the fact that the bytes of the file with the picture directly edit will not work, if it is not bmp.

{% - random encoder%}
After reading a little about the color models, I decided to abandon the decomposition of the image to 1 and 0 in favor of modifications of the pixels themselves in the RGB palette. For these manipulations, I chose the Pillow library, here is a good article about it.

So, we have an image. There are pixels in the image. Pixels are made up of primary colors — red, green, and blue.

Each of the colors is encoded with a number from 0 to 255.



We also have ASCII characters that are also encoded.

Let's try to encrypt some text in this image.

Picture:




Some text:
C makes it easy to shoot yourself in the foot; C ++ makes it harder
We connect the necessary libraries.

 from PIL import Image, ImageDraw from random import randint 

Then we will declare the function and place in it all the objects that will be useful to us.

 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') 

Further - more interesting. The most important task is to invent a way by which it will be possible to encrypt messages. I have proposed this method :

  1. Take the character, translate it into the ASCII number
  2. Create a tuple with random coordinate values
  3. We collect green and blue shades from a pixel by coordinates
  4. Replace the red hue with the character number in 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') 

Save the keys and the image.

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

code

We try to execute the script.

As a result, we got the same image, but in png format and with several changed pixels.



Now it remains to somehow decipher it.

We write a script to decrypt!

Connect everything you need.

 from PIL import Image from re import findall 

We declare the function to decrypt, as well as several objects.

 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]) 

Basic decryption algorithm:

 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]) 

These regular expressions are needed to read tuples from a text file.

The last action is to display the encrypted message.

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

code

And now let's try to get our message.



What was required to prove everything works!

The main drawback: the visibility of broken image pixels in the case of encrypting a large number of characters. However, this flaw is perfectly corrected by high resolution.

References:

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


All Articles