Esteganografía LSB

Érase unha vez que escribín o meu primeira publicación no hub. E ese post estaba adicado a un problema moi interesante, a esteganografía. Por suposto, a solución proposta nese vello tema non pode chamarse esteganografía no verdadeiro sentido da palabra. É só un xogo con formatos de ficheiro, pero un xogo bastante interesante.

Hoxe tentaremos afondar un pouco máis e mirar o algoritmo LSB. Se estás interesado, benvido baixo cat. (Debaixo do corte hai tráfico: preto dun megabyte).

En primeiro lugar, é necesario facer unha pequena introdución. Todo o mundo sabe que o propósito da criptografía é facer imposible ler información secreta. Por suposto, a criptografía ten as súas aplicacións, pero hai outro enfoque para a protección de datos. Non temos que cifrar a información, pero pretender que non a temos. Precisamente por iso se inventou a esteganografía. A Wikipedia asegúranos que “a esteganografía (do grego στεγανοσ - oculto e do grego γραφω - escribo, literalmente “escritura secreta”) é a ciencia da transmisión oculta de información mantendo en segredo o feito mesmo da transmisión.

Por suposto, ninguén prohibe combinar métodos criptográficos e esteganográficos. Ademais, na práctica fan isto, pero a nosa tarefa é comprender o básico. Se estudas detidamente o artigo da Wikipedia, descubrirás que os algoritmos de esteganografía inclúen os chamados. contedor e mensaxe. Un contedor é calquera información que axude a ocultar a nosa mensaxe secreta.

No noso caso, o contedor será unha imaxe en formato BMP. En primeiro lugar, vexamos a estrutura deste ficheiro. O ficheiro pódese dividir en 4 partes: cabeceira do ficheiro, cabeceira da imaxe, paleta e a propia imaxe. Para os nosos propósitos, só necesitamos saber o que está escrito na cabeceira.

Os dous primeiros bytes da cabeceira son a sinatura BM, despois o tamaño do ficheiro en bytes escríbese nunha palabra dobre, os seguintes 4 bytes están reservados e deben conter ceros e, finalmente, outra palabra dobre contén o desplazamento desde o principio do ficheiro aos bytes reais da imaxe. Nun ficheiro bmp de 24 bits, cada píxel está codificado con tres bytes BGR.

Agora xa sabemos como chegar á imaxe, só queda entender como podemos escribir alí a información que precisamos. Para iso necesitaremos o método LSB. A esencia do método é a seguinte: substituímos os bits menos significativos nos bytes responsables da codificación de cores. Digamos que se o byte seguinte da nosa mensaxe secreta é 11001011 e os bytes da imaxe son... 11101100 01001110 01111100 0101100111..., entón a codificación terá este aspecto. Dividiremos o byte da mensaxe secreta en 4 partes de dous bits: 11, 00, 10, 11 e substituiremos os bits de orde baixa da imaxe polos fragmentos resultantes: ...11101111 01001100 01111110 0101100111…. Tal substitución xeralmente non é perceptible para o ollo humano. Ademais, moitos dispositivos de saída máis antigos nin sequera poderán mostrar cambios tan pequenos.

Está claro que pode cambiar non só os 2 bits menos significativos, senón calquera número deles. Existe o seguinte patrón: cantos máis bits cambiemos, máis información podemos ocultar e máis interferencias provocará na imaxe orixinal. Por exemplo, aquí tes dúas imaxes:

Esteganografía LSB
Esteganografía LSB

A pesar dos meus mellores esforzos, non puiden ver a diferenza entre eles, pero con todo, na segunda imaxe, usando o método descrito, o poema de Lewis Carroll "The Hunting of the Snark" está oculto. Se leu ata aquí, probablemente estea interesado en coñecer a implementación. É bastante sinxelo, pero avisarei de inmediato de que todo está feito en Delphi. Hai dúas razóns para iso: 1. Creo que Delphi é unha boa lingua; 2. Este programa naceu no proceso de elaboración dun curso sobre os fundamentos da visión por ordenador, e os rapaces aos que lles estou a impartir este curso aínda non coñecen outra cousa que non sexa Delphi. Para aqueles que non estean familiarizados coa sintaxe, hai que explicar unha cousa: shl x é un desprazamento bit a bit á esquerda por x, shr x é un desprazamento bit bit á dereita por x.

Supoñemos que estamos escribindo texto almacenado nunha cadea no contedor e substituíndo os dous bytes inferiores:
Código de gravación:

para i:=1 to length(str) do
    comezar
      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.Posición:=f.Posición-1;
      tmp:=((tmp shr 2) shl 2)+l1;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Posición:=f.Posición-1;
      tmp:=((tmp shr 2) shl 2)+l2;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Posición:=f.Posición-1;
      tmp:=((tmp shr 2) shl 2)+l3;
      f.WriteBuffer(tmp,1);
 
      f.ReadBuffer(tmp,1);
      f.Posición:=f.Posición-1;
      tmp:=((tmp shr 2) shl 2)+l4;
      f.WriteBuffer(tmp,1);
 
    end;

código para ler:

for i:=1 to MsgSize do
    comezar
      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;

Ben, para os realmente preguiceiros... ligazón ao programa e ao seu código fonte.

Grazas.

Fonte: www.habr.com

Engadir un comentario