POLITECNICO DI BARI
Facoltà di Ingegneria
Corso di Laurea in Ingegneria Informatica
“Sicurezza dei Sistemi Informatici”
REALIZZAZIONE DI UNA
APPLICAZIONE DI
STEGANOGRAFIA IN JAVA USANDO
I FILE GRAFICI GIF E JPG
CONTENUTI






Steganografia
Struttura, memorizzazione, interpretazione di una
immagine
Compressione delle immagini
Formati GIF e JPG
Un esempio di steganografia in Java
Conclusioni
STEGANOGRAFIA
La steganografia è l’arte e la scienza di scrivere messaggi
segreti all’interno di un contenitore multimediale
(immagine, suono, ecc.) in modo che nessuno possa
conoscerne l’esistenza.
Obiettivi:
 nascondere in modo sicuro informazioni segrete e
private;
 proteggere i diritti sui dati quando sono coinvolti
interessi economici e profitti (watermarking).
STEGANOGRAFIA VS CRITTOGRAFIA
Steganografia
Crittografia
la rilevazione del messaggio nascosto
comporta il fallimento della tecnica di
steganografia.
l’esistenza del messaggio
è nota ma il significato è oscuro.
Soluzione ibrida:
steganografia e crittografia sono impiegate in maniera
combinata codificando il messaggio prima di inserirlo
all’interno del suo contenitore.
STRUTTURA, MEMORIZZAZIONE E INTERPRETAZIONE
DI UNA IMMAGINE (1)
Immagine
matrice di punti colorati detti pixel.
Pixel
quattro unsigned byte di dati:


3 byte rappresentano i colori rosso, verde e blu (color
byte);
1 byte rappresenta la trasparenza (alpha byte) .
STRUTTURA, MEMORIZZAZIONE E INTERPRETAZIONE
DI UNA IMMAGINE (2)
Ogni unsigned byte assume valori nell’intervallo 0 – 255.
Rappresentazione dei colori:




nero: R = G = B = 0;
bianco: R = G = B = 255;
tonalità di grigio: R = G = B = un valore nel range (0-255);
colore: unione di una certa quantità di rosso, verde e blu;
Possibili colori = (28)3 = 16.777.216
STRUTTURA, MEMORIZZAZIONE E INTERPRETAZIONE
DI UNA IMMAGINE (3)
Alpha byte:
0
il pixel è completamente trasparente senza tener
conto del valore dei color byte;
255
il pixel è completamente opaco con il
colore del pixel esclusivamente determinato dal
valore assunto dai tre color byte;
(0–255)
il pixel mostrerà il colore determinato dai tre
color byte in maniera sempre più evidente.
COMPRESSIONE DELLE IMMAGINI (1)
La compressione è l’atto di ridurre lo spazio occupato da
un oggetto, agendo sugli elementi costitutivi dell’oggetto
stesso.

In informatica un oggetto è un file, un insieme di file, e
cioè un insieme di bit.

Comprimere un oggetto informatico = diminuire il
numero di 1 e di 0, ovvero di bit, che lo compongono.

Compressione nel mondo fisico ≠ compressione nel
mondo informatico.
COMPRESSIONE DELLE IMMAGINI (2)
Come si attua la compressione?
Usando un algoritmo di compressione ossia un insieme dei
calcoli aventi per scopo la riduzione delle dimensioni di un
file o di un insieme di file.
Proprietà fondamentale di un algoritmo di compressione:
Reversibilità
capacità di leggere i file che sono stati
compressi con un particolare formato, ripristinando
l’informazione in essi contenuta, cioè decomprimendoli.
COMPRESSIONE DELLE IMMAGINI (3)
Esistono numerosi formati di compressione.
Le differenze sono date dalla misura della reversibilità:

Formato lossless
è in grado di restituire, al
termine della decompressione, un’immagine
esattamente uguale - pixel per pixel - all’originale
com’era prima che venisse compresso;

Formato lossy
non è in grado di assicurare una
reversibilità assoluta.
IL FORMATO GIF (1)
La sigla GIF sta per Graphics Interchange Format, un
formato grafico sviluppato alla fine degli anni ‘80 da
CompuServe. La compressione operata da GIF usa
l’algoritmo LZW, che è un criterio di compressione non
distruttivo.
L’algoritmo LZW usa un dizionario delle stringhe di simboli
ricorrenti nel file, costruito in modo tale che ad ogni nuovo
termine aggiunto al dizionario sia accoppiata in modo
esclusivo un’unica stringa. Il risparmio di spazio in un file
compresso con LZW dipende dal fatto che il numero di bit
necessari a codificare il “termine” che rappresenta una
stringa nel dizionario è inferiore al numero di bit necessari
a scrivere nel file non compresso tutti i caratteri che
compongono la stringa.
IL FORMATO GIF (2)

Fa uso di una tavolozza indicizzata di al più 256 colori
inglobati nel file GIF generato

sensibile perdita di informazioni quando l’immagine di
partenza è codificata in uno spazio colore RGB;

1 bit per pixel
immagini in bianco e nero;
al crescere del numero dei bit per pixel avremo formati
GIF con 4, 8, 16, 32, 64, 128 o 256 colori;
è prevista l’opzione interlacciamento;
due versioni: 87a e 89a. Quest’ultima supporta sia
trasparenza sia animazione.



STANDARD JPEG
JPEG (Joint Photographic Expert Group) è uno standard di
compressione distruttiva per le immagini a tono continuo sia a
colori sia in bianco e nero.
Da immagine non compressa a immagine compressa Jpeg:
1)
2)
3)
4)
5)
6)
Trasformazione dello spazio colore;
Riduzione, in base alla componente, di gruppi di pixel a
valori medi;
DCT applicata a blocchi di 8 x 8 pixel suddivisi in base alla
componente;
Divisione e arrotondamento all’intero dei 64 valori ottenuti
con la DCT;
Compressione non distruttiva dei coefficienti quantizzati;
Inserimento nel file compresso di intestazioni e parametri
per la decompressione.
UN ESEMPIO DI STEGANOGRAFIA
Analisi di una applicazione Java che, sfruttando i principi
della steganografia, consente di nascondere un messaggio
all’interno di una immagine.
Il file contenitore che ospiterà il messaggio da occultare è
una immagine nei formati gif o jpg.
STRUTTURA DELLA APPLICAZIONE DI
STEGANOGRAFIA
E’ composta da due programmi:

Il programma driver detto ImgDriver :
1)
2)
3)
4)
5)
6)

estrae i pixel da un’immagine;
converte i valori dei pixel in dati interi;
memorizza i valori dei pixel all’interno di un array tridimensionale di
interi;
passa l’array tridimensionale di interi all’ImgProcessing;
ottiene l’array tridimensionale di interi, modificato secondo l’algoritmo
di steganografia, dall’ImgProcessing;
visualizza l’immagine originale, l’immagine modificata ed una serie di
informazioni di output.
Il programma di processing detto ImgProcessing :
1)
2)
3)
riceve i valori dei pixel all’interno di un array tridimensionale di interi;
processa questi dati mediante l’algoritmo di steganografia
implementato;
restituisce un array tridimensionale di interi contenente i valori
modificati dei pixel.
APPLICAZIONE DI STEGANOGRAFIA (1)
Due versioni che differiscono unicamente per il programma
di processing impiegato.
Ciascun programma di processing implementa un diverso
algoritmo di steganografia:


ImgProcessingFourBit
un carattere per pixel;
caratteri a 8 bit; modifica i 4 LSB del rosso e del verde in
un pixel e memorizza il messaggio in pixel adiacenti.
ImgProcessingTwoBit
un carattere per pixel;
caratteri a 6 bit; modifica i 2 LSB del rosso, del verde e
del blu in un pixel, memorizza il messaggio a partire da
un pixel interno all’immagine e calcola un salto casuale
al successivo pixel da modificare.
APPLICAZIONE DI STEGANOGRAFIA (2)
Ciascuna versione dell’applicazione viene eseguita
digitando da linea di comando:
java ImgDriver ImgProcessingFourBit NomeImmagine
oppure
java ImgDriver ImgProcessingTwoBit NomeImmagine
Se non è specificata nessuna immagine da linea di
comando, il programma cercherà una immagine nella
directory corrente chiamata bandieraItalia.jpg.
Se nè il programma di processing nè l’immagine sono
specificati allora il programma verrà terminato mostrando
un messaggio di errore.
ImgDriver (1)
rawImage
oneDPix
threeDPix
threeDPix è
passato
al programma
di processing
Ottenuto con il metodo convertToThreeDim
Ottenuto con il metodo convertToOneDim
modImg



oneDPix
threeDPixMod
rawImage e modImg contengono rispettivamente l’immagine originale e l’immagine
modificata in forma grezza;
oneDPix è un 1D array di interi avente un pixel per elemento;
threeDPix e threeDPixMod sono 3D array di interi così strutturati:
int[righe][colonne][colori]
Le prime due dimensioni dell’array corrispondono alle righe e alle colonne
dell’immagine. La terza dimensione ha sempre 4 valori che corrispondono ai colori di
ciascun pixel così indicizzati:
0 alpha, 1 rosso, 2 verde, 3 blu
ImgDriver (2)
int[][][] convertToThreeDim(int[] oneDPix,int imgCols,int imgRows) {
//Si istanzia il 3D array che conterrà l'immagine.
int[][][] data = new int[imgRows][imgCols][4];
for(int row = 0; row < imgRows; row++) {
//Si estrae una riga di pixel per volta e la si memorizza in un array di interi temporaneo.
int[] aRow = new int[imgCols];
for(int col = 0; col < imgCols; col++) {
int element = row * imgCols + col;
aRow[col] = oneDPix[element];
} //end for loop su colonne.
//Si spostano i dati della riga nel 3D array. Si fa uso dell'operazione
//di AND bit a bit e dello SHIFT a destra per selezionare i dati corretti.
for(int col = 0; col < imgCols; col++) {
//Alpha
data[row][col][0] = (aRow[col] >> 24) & 0xFF;
//Rosso
data[row][col][1] = (aRow[col] >> 16) & 0xFF;
//Verde
data[row][col][2] = (aRow[col] >> 8) & 0xFF;
//Blu
data[row][col][3] = (aRow[col]) & 0xFF;
} //end for loop su colonne.
} //end for loop su righe.
return data;
} //end convertToThreeDim
ImgDriver (3)
int[] convertToOneDim(int[][][] data,int imgCols,int imgRows) {
//Si istanzia il 1D array che conterrà i pixel dell'immagine come interi.
int[] oneDPix = new int[imgCols * imgRows];
//Si spostano i dati nel 1D array. Si fa uso degli
//operatori di OR bit a bit e di SHIFT a sinistra
//per mettere i quattro byte in un dato intero.
for(int row = 0,cnt = 0; row < imgRows; row++) {
for(int col = 0; col < imgCols; col++) {
oneDPix[cnt] = ((data[row][col][0] << 24) & 0xFF000000) | ((data[row][col][1] << 16) & 0x00FF0000)
| ((data[row][col][2] << 8) & 0x0000FF00) | ((data[row][col][3]) & 0x000000FF);
cnt++;
} //end for loop su colonne.
} //end for loop su righe.
return oneDPix;
} //end convertToOneDim
PROGRAMMA DI PROCESSING (1)
Entrambe i programmi di processing ImgProcessingFourBit
e ImgProcessingTwoBit implementano l’interfaccia
ImgInterface:
import java.io.*;
interface ImgInterface {
int[][][] processImg (int[][][] threeDPix, int imgRows, int imgCols) throws IOException;
} //end ImgInterface
Il primo parametro è un reference al 3D array di interi (contenente il
valore dei pixel non modificati), il secondo ed il terzo sono
rispettivamente il numero di righe e di colonne dell’immagine. Il metodo
restituisce un 3D array di interi contenente il valore dei pixel modificati
secondo l’algoritmo di steganografia implementato nel corpo del
metodo.
PROGRAMMA DI PROCESSING (2)
da
ImgDriver
threeDPix
imgRows
imgCols
processImg
temp3D
a
ImgDriver
immagine modificata




threeDPix è il 3D array di interi costruito da ImgDriver a
partire dalla immagine originale;
imgRows e imgCols sono righe e colonne dell’immagine;
processImg è il metodo implementato dal programma di
processing per realizzare l’algoritmo di steganografia;
temp3D è il 3D array di interi modificato restituito a
ImgDriver.
ImgProcessingFourBit
inserimento messaggio
temp3D
msg
copia di threeDPix stringa contenente
testo nello
standard Unicode
msgBytes
fourBitBytes
testo a 8 bit
per carattere
array contenente
un gruppo da 4 bit
per byte
temp3D
3D array modificato
con un carattere
per pixel
estrazione messaggio


temp3D
ExtractedFourBitBytes
extracedMsg
3D array modificato
con un carattere
per pixel
array contenente
un gruppo da 4 bit
per byte
stringa contenente
testo estratto nello
standard Unicode
ciascuno dei due gruppi di bit in un carattere da 8 bit viene memorizzato nei 4 LSB
del rosso e del verde del pixel selezionato;
i caratteri sono memorizzati a partire da un punto interno all’immagine e sempre in
pixel adiacenti.
ImgProcessingTwoBit
inserimento messaggio
temp3D
msg
msgUpper
copia di threeDPix stringa contenente stringa con
testo nello
caratteri in
standard Unicode maiuscolo-32
msgBytes
twoBitBytes
testo a 6 bit
per carattere
array contenente
una coppia di bit
per byte
temp3D
3D array modificato
con un carattere
per pixel
estrazione messaggio



temp3D
ExtractedTwoBitBytes
extracedMsg
3D array modificato
con un carattere
per pixel
array contenente
una coppia di bit
per byte
stringa contenente
testo estratto nello
standard Unicode
ciascuna delle tre coppie di bit in un carattere da 6 bit viene memorizzata nei 2 LSB del rosso,
verde e blu del pixel prescelto;
il messaggio è nascosto a partire da un qualsiasi pixel interno all’immagine;
il messaggio non è nascosto in pixel tra loro adiacenti. Si usa il valore contenuto nei 2 LSB del blu
per determinare il numero di pixel da saltare prima di modificare un altro pixel.
CONCLUSIONI
ImgProcessingFourBit :
 semplice e poco accorto nel modificare i bit meno
significativi dei color byte;
 l’introduzione
di un breve messaggio all’interno
dell’immagine può essere rilevata da parte di un
osservatore;
 la presenza del messaggio sarebbe ancora più evidente
se il testo da inserire fosse abbastanza lungo.
ImgProcessingTwoBit :
 ottimi risultati sia nel caso di messaggi brevi che nel
caso di messaggi lunghi;
 modifica di 2 soli LSB per color byte;
 il successivo pixel da modificare è scelto in modo
casuale in base al valore assunto dai 2 LSB del blu nel
pixel appena modificato.