Steganografia in un’immagine jpeg – JAVA

Steganografia jpeg

La steganografia è una tecnica usata per nascondere una comunicazione tra due interlocutori, il significato dal greco è appunto "scrittura coperta".
Questa tecnica nel mondo digitale nasconde all'interno di un qualsiasi file senza alterare le funzioni principali del file.
La tecnica è più semplice di quanto si pensa, sappiamo che un'immagine è formata da byte e ogni byte viene definito con un numero esadecimale, se andassimo a vedere con un hex editor più immagini jpeg possiamo vedere che in ogni immagine i primi due byte sono FFD8 e e l'ultimi due byte dell'immagine FFD9.
Quindi sapendo che la rappresentazione binaria dell'immagine ha un inizio e una fine, molto semplicemente potremmo aggiungere isteganografia jpegnformazioni alla fine, questa è una delle tecniche di steganografia più semplice ma anche più facile da capire per chi non è mai entrato in questo argomento.

Come possiamo vedere l'immagine inizia con FFD8, finisce con FFD9 e sotto l'ultimo byte c'è uno spazio vuoto dove si potrebbe andare ad inserire altri dati.

 

 

 

 

 

 

 

 

 

ho creato una classe che usa questa tecnica unita alla tecnica della crittografia su delle immagini JPEG, questa classe prende il percorso dell'immagine e il testo che si vuole inserire all'interno, il testo verrà criptato e inserito dopo il codice FFD9.

Risorse:
Steganografia.zip (ImgSteganografia.java, AES.java)

ImgSteganografia.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;


public class ImgSteganografia {
    
    private String fileName;
    private String key = "123456789abcdefg";
    
    /**
     * Costruttore
     * 
     * @param fileName - path dell'immagine
     */
    public ImgSteganografia(String fileName, boolean crypt){
        if(crypt){
            // Copio il file        
            String nome[] = fileName.split(".jpg");
            nome[0] += "_steganografia.jpg";
            File f = new File(nome[0]);
            f.delete();
            copiaFile(fileName, nome[0]);
            fileName = nome[0];
        }
        this.fileName = fileName;
        
    }
    
    /**
     * Metodo che cripta il testo in AES e lo inserisce nel file
     * 
     * @param testo - testo da inserire
	 * @return posizione del testo nel file
     */
    public long crypt(String testo){
        long posizione = 0;
        try {
            RandomAccessFile f = new RandomAccessFile(fileName, "rw");
            int dati = 0;
            byte[] chiper;
            dati = f.read();
			// Rendo il testo di lunghezza multiplo di 16
			// così da poter usare la crittografia AES
            while(testo.length() % 16 != 0){
                testo += '\0';
            }
            // Cerco l'inizio dell'immagine
            while(dati != -1){
                if(dati == 0xFF){
                    dati = f.read();
                    if(dati == 0xD8){
                        dati = -1;
                        continue;
                    }
                }
            }
            dati = f.read();
            // Cerco la fine dell'immagine
            while(dati != -1){
                if(dati == 0xFF){
                    dati = f.read();
                    if(dati == 0xD9){
						// cripto il testo
                        chiper = AES.encrypt(testo, key);
						// inserisco il testo criptato
                        f.write(chiper);
						// inserisco un segnaposto per ritrovare la fine del testo
                        byte fine[] = "END".getBytes("UTF-8");
                        f.write(fine);
                        posizione = f.getFilePointer();
                        dati = -1;
                        continue;
                    }
                }
                dati = f.read();
            }
            f.close();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return posizione;
    }
    
    /**
     * Metodo che decripta il testo nel file
     * 
     * @return testo decifrato
     */
    public String decrypt(){
        String testo = "";
        boolean flag = false;
        
        try {
            RandomAccessFile f = new RandomAccessFile(fileName, "r");
            int dati = 0;
            int datiChiper = 0;
            long posInizioChiper = 0;
            long posFineChiper = 0;
            int flagFine = 0;
            int i = 0;
            byte[] chiper = null;
            dati = f.read();
            // Cerco l'inizio dell'immagine
            while(dati != -1){
                if(dati == 0xFF){
                    dati = f.read();
                    if(dati == 0xD8){
                        dati = -1;
                        continue;
                    }
                }
            }
            dati = f.read();       
            // cerco la fine dell'immagine 
            // e leggo il testo cifrato
            while(dati != -1){
                if(dati == 0xFF){
                    dati = f.read();
                    if(dati == 0xD9){
                        // salvo l'inizio del testo cifrato
                        posInizioChiper = f.getFilePointer();
                        // cerco la fine del testo cifrato
                        datiChiper = f.read();
                        while(datiChiper != -1){
                            if(datiChiper == "E".charAt(0)){
                                datiChiper = f.read();
                                if(datiChiper == "N".charAt(0)){
                                    datiChiper = f.read();
                                    if(datiChiper == "D".charAt(0)){
                                        // salvo la fine del testo cifrato
                                        posFineChiper = f.getFilePointer() - 3;
                                    }
                                }
                            }
                            datiChiper = f.read();
                        }
                        
                        // Leggo il testo cifrato nel file
                        f.seek(posInizioChiper);
                        if(f.getFilePointer() != f.length()){
                            chiper = new byte[(int)(posFineChiper - posInizioChiper)];
                            f.read(chiper);
                            flag = true;
                        }
                        // finisco il ciclo
                        dati = -1;
                        continue;
                    }
                }
                dati = f.read();
            }
            // decripto il testo cifrato
            if(flag){
                testo = AES.decrypt(chiper, key);
            }
            
            f.close();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
        return testo;
    }
    
    /**
     * Metodo copy
     * 
     * copia un file su un'altro
     * 
     * @param srFile file sorgente
     * @param dtFile file destinazione
     */
    private static void copiaFile(String srFile, String dtFile) {
        try {
            File f1 = new File(srFile);
            File f2 = new File(dtFile);
            InputStream in = new FileInputStream(f1);
            OutputStream out = new FileOutputStream(f2, true);
            byte[] buf = new byte[1024];
            int len;
			while ((len = in.read(buf)) > 0) {
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
		}catch (FileNotFoundException ex) {
            ex.printStackTrace();
            System.exit(0);
		}catch (IOException e) {
            System.out.println(e.getMessage());
		}
    }
    
	
	/**
	* Cerca la fine dell'immagine
	*
	* @return posizione della fine
	*/
    public long cercaFine(){
        long posizione = 0;
        try {
            RandomAccessFile f = new RandomAccessFile(fileName, "r");
            int dati = 0;
            dati = f.read();
            
            // Cerco l'inizio dell'immagine
            while(dati != -1){
                if(dati == 0xFF){
                    dati = f.read();
                    if(dati == 0xD8){
                        dati = -1;
                        continue;
                    }
                }
            }
            dati = f.read();
            // Cerco la fine del file
            while(dati != -1){
                if(dati == 0xFF){
                    dati = f.read();
                    if(dati == 0xD9){
                        posizione = f.getFilePointer();
                        // fermo il while
                        dati = -1;
                        continue;
                    }
                }
                dati = f.read();
            }
            f.close();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return posizione;
    }
    
	
	/**
	* Cerca la fine del testo inserito
	*
	* @return posizione della fine del testo
	*/
    public long cercaFineTesto(){
        long posizione = 0;
        try {
            RandomAccessFile f = new RandomAccessFile(fileName, "r");
            int dati = 0;
            int datiChiper = 0;
            
            dati = f.read();
            
            // Cerco l'inizio dell'immagine
            while(dati != -1){
                if(dati == 0xFF){
                    dati = f.read();
                    if(dati == 0xD8){
                        dati = -1;
                        continue;
                    }
                }
            }
            dati = f.read();
            // Cerco la fine del file
            while(dati != -1){
                if(dati == 0xFF){
                    dati = f.read();
                    if(dati == 0xD9){
                        // cerco la fine del testo cifrato
                        datiChiper = f.read();
                        while(datiChiper != -1){
                            if(datiChiper == "E".charAt(0)){
                                datiChiper = f.read();
                                if(datiChiper == "N".charAt(0)){
                                    datiChiper = f.read();
                                    if(datiChiper == "D".charAt(0)){
                                        // salvo la fine del testo cifrato
                                        posizione = f.getFilePointer() + 1;
                                    }
                                }
                            }
                            datiChiper = f.read();
                        }
                        // fermo il while
                        dati = -1;
                        continue;
                    }
                }
                dati = f.read();
            }
            f.close();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return posizione;
    }
}

Creare un finestra JFrame – JAVA

 

Precedente Creare un file immagine bitmap (*.bmp) - C/C++ Successivo Creare una comunicazione usando i socket - JAVA(client) e PHP(server)