Esteganografia LSB

Era uma vez eu escrevi meu primeira postagem no hub. E esse post foi dedicado a um problema muito interessante, nomeadamente a esteganografia. É claro que a solução proposta naquele antigo tópico não pode ser chamada de esteganografia no verdadeiro sentido da palavra. É apenas um jogo com formatos de arquivo, mas mesmo assim é um jogo bastante interessante.

Hoje tentaremos nos aprofundar um pouco mais e examinar o algoritmo LSB. Se você estiver interessado, será bem-vindo no gato. (Sob o corte está o tráfego: cerca de um megabyte.)

Antes de mais nada é necessário fazer uma breve introdução. Todo mundo sabe que o objetivo da criptografia é impossibilitar a leitura de informações secretas. É claro que a criptografia tem suas aplicações, mas existe outra abordagem para a proteção de dados. Não precisamos criptografar as informações, mas fingir que não as temos. É precisamente por isso que a esteganografia foi inventada. A Wikipedia nos garante que “a esteganografia (do grego στεγανοσ - oculto e do grego γραφω - escrevo, literalmente “escrita secreta”) é a ciência da transmissão oculta de informações, mantendo em segredo o próprio fato da transmissão.

É claro que ninguém proíbe combinar métodos criptográficos e esteganográficos. Além disso, na prática eles fazem isso, mas nossa tarefa é entender o básico. Se você estudar cuidadosamente o artigo da Wikipedia, descobrirá que os algoritmos de esteganografia incluem os chamados. contêiner e mensagem. Um contêiner é qualquer informação que ajude a ocultar nossa mensagem secreta.

No nosso caso, o container será uma imagem em formato BMP. Primeiro, vamos dar uma olhada na estrutura deste arquivo. O arquivo pode ser dividido em 4 partes: cabeçalho do arquivo, cabeçalho da imagem, paleta e a própria imagem. Para nossos propósitos, só precisamos saber o que está escrito no cabeçalho.

Os dois primeiros bytes do cabeçalho são a assinatura BM, depois o tamanho do arquivo em bytes é escrito em uma palavra dupla, os próximos 4 bytes são reservados e devem conter zeros e, por fim, outra palavra dupla contém o deslocamento do início do arquivo para os bytes reais da imagem. Em um arquivo bmp de 24 bits, cada pixel é codificado com três bytes BGR.

Agora que sabemos como chegar à imagem, só falta entender como podemos escrever ali as informações que precisamos. Para isso precisaremos do método LSB. A essência do método é a seguinte: substituímos os bits menos significativos nos bytes responsáveis ​​​​pela codificação de cores. Digamos que se o próximo byte da nossa mensagem secreta for 11001011, e os bytes na imagem forem...11101100 01001110 01111100 0101100111..., então a codificação ficará assim. Dividiremos o byte da mensagem secreta em 4 partes de dois bits: 11, 00, 10, 11 e substituiremos os bits de ordem inferior da imagem pelos fragmentos resultantes: ...11101111 01001100 01111110 0101100111…. Tal substituição geralmente não é perceptível ao olho humano. Além disso, muitos dispositivos de saída mais antigos nem serão capazes de exibir essas pequenas alterações.

É claro que você pode alterar não apenas os 2 bits menos significativos, mas qualquer número deles. Existe o seguinte padrão: quanto mais bits alterarmos, mais informações poderemos ocultar e mais interferência isso causará na imagem original. Por exemplo, aqui estão duas imagens:

Esteganografia LSB
Esteganografia LSB

Apesar dos meus melhores esforços, não consegui ver a diferença entre eles, mas mesmo assim, na segunda imagem, usando o método descrito, o poema de Lewis Carroll “The Hunting of the Snark” está escondido. Se você leu até aqui, provavelmente está interessado em aprender sobre a implementação. É bem simples, mas já aviso que tudo é feito em Delphi. Há duas razões para isso: 1. Acho Delphi uma boa linguagem; 2. Este programa nasceu no processo de preparação de um curso sobre noções básicas de visão computacional, e os caras para quem estou ministrando este curso ainda não sabem nada além de Delphi. Para aqueles que não estão familiarizados com a sintaxe, uma coisa precisa ser explicada: shl x é um deslocamento bit a bit para a esquerda por x, shr x é um deslocamento bit a bit para a direita por x.

Assumimos que estamos escrevendo o texto armazenado em uma string no contêiner e substituindo os dois bytes inferiores:
Código de gravação:

para i:=1 para comprimento(str) faça
    começar
      l1:=byte(str[i]) shr 6;
      l2:=byte(str[i]) shl 2; l2:=l2 shr 6;
      l3:=byte(str[i]) shl 4; l3:=l3 shr 6;
      l4:=byte(str[i]) shl 6; l4:=l4 shr 6;
 
      f.ReadBuffer(tmp,1);
      f.Posição:=f.Posição-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Posição:=f.Posição-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Posição:=f.Posição-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Posição:=f.Posição-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    end;

código para ler:

para i:=1 para MsgSize faça
    começar
      f.ReadBuffer(tmp,1);
      l1:=tmp shl 6;
      f.ReadBuffer(tmp,1);
      l2:=tmp shl 6; l2:=l2 shr 2;
      f.ReadBuffer(tmp,1);
      l3:=tmp shl 6; l3:=l3 shr 4;
      f.ReadBuffer(tmp,1);
      l4:=tmp shl 6; l4:=l4 shr 6;
      str:=str+char(l1+l2+l3+l4);
    end;

Bem, para os realmente preguiçosos - link para o programa e seu código fonte.

Obrigado.

Fonte: habr.com

Adicionar um comentário