
Esteganografia em Python | Ocultar ficheiros ou dados em ficheiros de imagem
Este script ocultará arquivos dentro de imagens e salvará a imagem modificada no disco
O tamanho máximo de arquivo que pode ser ocultado dentro de uma imagem depende da dimensão da imagem.
max_file_size = ( height_of_image * width_of_image * 6 / 8 ) bytes
'100k words.txt' está oculto em 'original_image.png' com o nome 'image_with_100k words.png'. Vá e veja se consegue notar a diferença entre essas duas imagens. Você pode usar este Módulo para extrair '100k words.txt' de 'image_with_100k words.png'
Imagem Original

Imagem Modificada

Esta imagem contém 100k palavras (um arquivo de texto) ocultas dentro dela!
Baseia-se em um princípio simples: se alterarmos o LSB (Bits Menos Significativos) de cada Pixel, a mudança não será significativa e não será percebida pelos olhos.
Então, este Módulo pega 2 bits de dados do arquivo a ser ocultado e substitui os últimos 2 bits de um pixel por esses 2 bits, e então passa para o próximo pixel. A mudança máxima em um pixel pode ser de 4 unidades, e a faixa de valores em uma imagem PNG é (0,255), então essa mudança não será significativa.
Em uma imagem PNG, cada pixel possui 3 canais: Vermelho, Verde e Azul. (Algumas imagens PNG têm 1 ou 4 canais, mas este Programa os converterá para 3 canais) Um pixel típico em uma imagem PNG se parece com:
a_pixel = (17,32,11) # (RED, GREEN, BLUE)
Então, podemos salvar 3 vezes 2 bits em um Pixel, ou seja, 6 bits por pixel. Isso nos leva ao limite superior do tamanho do arquivo que pode ser ocultado em uma imagem:
max_file_size = ( height_of_image * width_of_image * 6 / 8 ) bytes
Vamos entender usando um exemplo. Os dados a serem ocultados são:
binary_data = 0b100111
Vamos pegar os primeiros dois bits e substituí-los pelo Canal VERMELHO do nosso 'a_pixel'.
a_pixel = (0b10001, 0b100000, 0b1011) # binary representation of a_pixel values
# Let's change a_pixel's RED Channel
# 0b10001 -> 0b10010 ( First 2 bits are 10 )
a_pixel = (0b10010, 0b100000, 0b1011) # modified pixel
Vamos novamente pegar 2 bits de binary_data e substituir os últimos 2 bits do Canal VERDE com eles.
a_pixel = (0b10010, 0b100000, 0b1011)
# Let's change a_pixel's GREEN Channel
# 0b100000 -> 0b100001 ( The 2 bits are 01 )
a_pixel = (0b10010, 0b100001, 0b1011) # modified pixel
Vamos fazer isso mais uma vez com o Canal AZUL e terminaremos.
a_pixel = (0b10010, 0b100001, 0b1011)
# Let's change a_pixel's BLUE Channel
# 0b1011 -> 0b1011 ( The 2 bits are 11 ) ; Notice that the value wasn't changed this time
a_pixel = (0b10010, 0b100001, 0b1011) # pixel wasn't modified this time
Então, ocultamos nossa mensagem de 6 bits em um pixel, vamos ver as mudanças no pixel
a_pixel = (0b10001, 0b100000, 0b1011) = (17, 32, 11)
a_pixel_with_data = (0b10010, 0b100001, 0b1011) = (18, 33, 11)
Como podemos ver, a mudança nem é perceptível no nível do pixel. O Módulo faz isso repetidamente até que todos os nossos dados sejam salvos na imagem.

NOTA : O ruído na foto é aumentado e, se usarmos qualquer software de edição de fotos e compararmos com a imagem original, esta imagem terá muito mais ruído do que a imagem original.
Solução para este problema: Nunca faça upload/compartilhe a imagem original na internet
MIT
Software Livre, Com Certeza!