Tempo fa scrissi il mio . Quel post riguardava un problema piuttosto interessante, ossia la steganografia. Certo, la soluzione proposta in quel vecchio argomento non può essere definita steganografia nel senso vero del termine. È solo un gioco con i formati di file, ma, comunque, è un gioco piuttosto interessante.
Oggi proveremo a scavare un po' più a fondo e esamineremo l'algoritmo LSB. Se siete interessati, vi invito a proseguire. (Sotto il tag, il traffico: circa un megabyte.)
Prima di tutto, è necessario fare una piccola introduzione. È ben noto che lo scopo della crittografia è rendere impossibile la lettura delle informazioni segrete. Naturalmente, la crittografia ha i suoi ambiti di applicazione, ma esiste anche un altro approccio alla protezione dei dati. Si può non cifrare l'informazione, ma far finta di non averla. È proprio per questo che è stata inventata la steganografia. Wikipedia ci assicura che "la steganografia (dal greco στεγανοσ — nascosto e γραφω — scrivo, letteralmente "scrittura segreta") è la scienza della trasmissione nascosta di informazioni mediante la segretezza del fatto stesso della trasmissione.
Naturalmente, non è vietato combinare metodi crittografici e steganografici. Anzi, nella pratica si fa proprio così, ma il nostro compito è comprendere le basi. Se si studia attentamente l'articolo di Wikipedia, si scopre che negli algoritmi di steganografia compaiono il cosiddetto contenitore e il messaggio. Il contenitore è qualsiasi informazione che aiuti a nascondere il nostro messaggio segreto.
Nel nostro caso, il contenitore sarà un'immagine in formato BMP. Iniziamo a esaminare la struttura di questo file. Il file può essere convenzionalmente suddiviso in 4 parti: l'intestazione del file, l'intestazione dell'immagine, la palette e l'immagine stessa. Per i nostri scopi, è sufficiente sapere solo ciò che è registrato nell'intestazione.
I primi due byte dell'intestazione sono la firma BM, poi in una parola doppia è registrata la dimensione del file in byte, i successivi 4 byte sono riservati e devono contenere zeri e, infine, in un'altra parola doppia è registrato lo spostamento dall'inizio del file ai byte dell'immagine. In un file bmp a 24 bit, ogni pixel è codificato da tre byte BGR.
Ora sappiamo come accedere all'immagine, resta da capire come possiamo registrare le informazioni di cui abbiamo bisogno. A questo scopo ci verrà in aiuto il metodo LSB. La sostanza del metodo consiste nel seguente: sostituiamo i bit meno significativi dei byte che si occupano della codifica del colore. Supponiamo che un byte del nostro messaggio segreto sia 11001011, e i byte nell'immagine siano…11101100 01001110 01111100 0101100111…, allora la codifica apparirà così. Divideremo il byte del messaggio segreto in 4 parti di due bit: 11, 00, 10, 11, e sostituiremo i bit meno significativi dell'immagine: …11101111 01001100 01111110 0101100111…. Questa sostituzione, in generale, non è percepibile dall'occhio umano. Inoltre, molti dispositivi di output più vecchi potrebbero non essere in grado di visualizzare tali modifiche insignificanti.
È chiaro che possiamo cambiare non solo 2 bit meno significativi, ma anche qualsiasi numero di essi. Qui c'è una regola: maggiore è il numero di bit che cambiamo, maggiore sarà la quantità di informazioni che possiamo nascondere, e maggiori saranno le interferenze nell'immagine originale. Ad esempio, ecco due immagini:


Per quanto desiderassi, non sono riuscito a vedere la differenza tra di esse, eppure nella seconda immagine è stata nascosta, con il metodo descritto, la poesia di Lewis Carroll "La caccia allo Snark". Se sei arrivato fin qui, sicuramente ti interesserà conoscere anche l'implementazione. È piuttosto semplice, ma avverto subito che è stata realizzata interamente in Delphi. Ci sono due motivi per questo: 1. Ritengo che Delphi sia un buon linguaggio; 2. Questo programma è nato durante la preparazione di un corso sulle basi della visione artificiale, e i ragazzi a cui insegno non conoscono altro che Delphi. Per coloro che non sono familiari con la sintassi, occorre spiegare una cosa: shl x – scorrimento a sinistra di x bit, shr x – scorrimento a destra di x bit.
Consideriamo che stiamo registrando in un contenitore del testo contenuto in una stringa e sostituiamo i due byte meno significativi:
Codice per la scrittura:
for i:=1 to length(str) do
begin
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.Position:=f.Position-1;
tmp:=((tmp shr 2) shl 2)+l1;
f.WriteBuffer(tmp,1);
f.ReadBuffer(tmp,1);
f.Position:=f.Position-1;
tmp:=((tmp shr 2) shl 2)+l2;
f.WriteBuffer(tmp,1);
f.ReadBuffer(tmp,1);
f.Position:=f.Position-1;
tmp:=((tmp shr 2) shl 2)+l3;
f.WriteBuffer(tmp,1);
f.ReadBuffer(tmp,1);
f.Position:=f.Position-1;
tmp:=((tmp shr 2) shl 2)+l4;
f.WriteBuffer(tmp,1);
end;
codice per la lettura:
for i:=1 to MsgSize do
begin
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 shl 6;
str:=str+char(l1+l2+l3+l4);
end;
E per i davvero pigri – .
Grazie.
Fonte: habr.com
