4 Replies - 3643 Views - Last Post: 26 April 2012 - 03:43 AM Rate Topic: -----

#1 sav10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 17-August 11

Video Steganography

Posted 02 March 2012 - 10:17 PM

I have a code for Video Steganography using LSb,but am not able to figure out where exactly the lsb part is implemnted.Can any1 tell me where is this happening.As far as i have understood this code.?This program is only appending the data file bytes to the video or any file.The code is:
import java.io.*;
import java.nio.ByteBuffer;
import java.util.zip.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;


public class VideoSteganography
{
    public static final int OFFSET_JPG= 3;
    public static final int OFFSET_PNG= 42;
    public static final int OFFSET_GIF_BMP_TIF= 32;
    public static final short HEADER_LENGTH= 15* 4;
    public static final byte[] VERSION_BYTE= {'2','0','0'};
    public static final byte UUF= 1;
    public static final byte UEF= 2;
    public static final byte CUF= 3;
    public static final byte CEF= 4;

    private static Cipher cipher;

    private static SecretKeySpec spec;
    private static String masterExtension, message;

    private static File masterFile;

    private static byte features;
    private static int inputFileSize;
    private static int i, j, inputOutputMarker, messageSize, tempInt;
    private static short compressionRatio= 0, temp;
    private static byte byte1, byte2, byte3, byteArrayIn[];
    private static ByteArrayOutputStream byteOut;

    private VideoSteganography()
    {
        System.out.println("Steganography  ready...");
    }

    public static String getMessage()
    {
        return message;
    }




    public static boolean embedFile(File masterFile, File outputFile, File dataFile, int compression, String password)
    {
        messageSize= (int) dataFile.length();

        if(password!= null && password.length()<16)
        {
            message= "Password should be minimum of 16 Characters";
            return false;
        }

        if(compression!= 0)
        {

            if(compression< 0)      compression= 0;
            if(compression>9)       compression= 9;

            if(password== null) features= CUF;
            else                    features= CEF;
        }
        else
        {
            if(password== null) features= UUF;
            else                    features= UEF;
        }

        inputFileSize= (int) masterFile.length();
        try
        {

            byteOut= new ByteArrayOutputStream();

// create a byte array of length equal to size of input file
            byteArrayIn= new byte[inputFileSize];

            // Open the input file read all bytes into byteArrayIn
            DataInputStream in= new DataInputStream(new FileInputStream(masterFile));
            in.read(byteArrayIn, 0, inputFileSize);
            in.close();

            String fileName= masterFile.getName();
            masterExtension= fileName.substring(fileName.length()-3, fileName.length());

            if(masterExtension.equalsIgnoreCase("jpg"))
            {
                // Skip past OFFSET_JPG bytes
                byteOut.write(byteArrayIn, 0, OFFSET_JPG);
                inputOutputMarker= OFFSET_JPG;
            }
            else if(masterExtension.equalsIgnoreCase("png"))
                    {

                        byteOut.write(byteArrayIn, 0, OFFSET_PNG);
                        inputOutputMarker= OFFSET_PNG;
                    }
                  else
                    {

                        byteOut.write(byteArrayIn, 0, OFFSET_GIF_BMP_TIF);
                        inputOutputMarker= OFFSET_GIF_BMP_TIF;
                    }


            // Convert the 32 bit input file size into byte array
            byte tempByte[]= new byte[4];
            for(i=24, j=0; i>=0; i-=8, j++)
            {
                tempInt= inputFileSize;
                tempInt>>= i;
                tempInt&= 0x000000FF;
                tempByte[j]= (byte) tempInt;
            }

            // Embed 4 byte input File size array into the master file

            embedBytes(tempByte);


            byteOut.write(byteArrayIn, inputOutputMarker, inputFileSize- inputOutputMarker);
            inputOutputMarker= inputFileSize;




            writeBytes(VERSION_BYTE);
            writeBytes(new byte[]{features});

            // Read the data bytes into fileArray
            byte []fileArray= new byte[messageSize];
            in= new DataInputStream(new FileInputStream(dataFile));
            in.read(fileArray, 0, messageSize);
            in.close();

            if(features== CUF || features== CEF)
            {
                ByteArrayOutputStream arrayOutputStream= new ByteArrayOutputStream();
                ZipOutputStream zOut= new ZipOutputStream(arrayOutputStream);
                ZipEntry entry= new ZipEntry(dataFile.getName());
                zOut.setLevel(compression);
                zOut.putNextEntry(entry);
                zOut.write(fileArray, 0, messageSize);
                zOut.closeEntry();
                zOut.finish();
                zOut.close();

            // Get the compressed message byte array
                fileArray= arrayOutputStream.toByteArray();
                compressionRatio= (short) ((double)fileArray.length / (double)messageSize * 100.0);
                messageSize= fileArray.length;
            }

            // Embed 1 byte compression ratio into the output file
            writeBytes(new byte[]{(byte) compressionRatio});


            if(features== UEF || features== CEF)
            {
                Cipher cipher= Cipher.getInstance("AES");
                SecretKeySpec spec= new SecretKeySpec(password.substring(0, 16).getBytes(), "AES");
                cipher.init(Cipher.ENCRYPT_MODE, spec);
                fileArray= cipher.doFinal(fileArray);
                messageSize= fileArray.length;
            }

            tempByte= new byte[4];
            for(i=24, j=0; i>=0; i-=8, j++)
            {
                tempInt= messageSize;
                tempInt>>= i;
                tempInt&= 0x000000FF;
                tempByte[j]= (byte) tempInt;
            }

            writeBytes(tempByte);

            // Embed the message
            writeBytes(fileArray);

            DataOutputStream out= new DataOutputStream(new FileOutputStream(outputFile));
            byteOut.writeTo(out);
            out.close();
        }
        catch(EOFException e)
        {
        }
        catch(Exception e)
        {
            message= "Oops!!\nError: "+ e.toString();
            e.printStackTrace();
            return false;
        }

        message= "File '"+ dataFile.getName()+ "' embedded successfully in file '"+ outputFile.getName()+ "'.";
        return true;
    }

// Retrieves an embedded file from a Master file
public static boolean retrieveFile(SteganoInformation info, String password, boolean overwrite)
    {
        File dataFile= null;
        features= info.getFeatures();

        try
        {
            masterFile= info.getFile();
            byteArrayIn= new byte[(int) masterFile.length()];

            DataInputStream in= new DataInputStream(new FileInputStream(masterFile));
            in.read(byteArrayIn, 0, (int)masterFile.length());
            in.close();

            messageSize= info.getDataLength();
            byte[] fileArray= new byte[messageSize];
            inputOutputMarker= info.getInputMarker();
            readBytes(fileArray);

            if(messageSize<=0)
            {
                message= "Unexpected size of embedded file: 0.";
                return false;
            }


            if(features== CEF || features== UEF)
            {
                password= password.substring(0, 16);
                byte passwordBytes[]= password.getBytes();
                cipher= Cipher.getInstance("AES");
                spec= new SecretKeySpec(passwordBytes, "AES");
                cipher.init(Cipher.DECRYPT_MODE, spec);
                try
                {
                    fileArray= cipher.doFinal(fileArray);
                }
                catch(Exception bp)
                {
                    message= "Incorrent Password";
                    bp.printStackTrace();
                    return false;
                }
                messageSize= fileArray.length;
            }


            if(features== CUF || features== CEF)
            {
                ByteArrayOutputStream by= new ByteArrayOutputStream();
                DataOutputStream out= new DataOutputStream(by);

                ZipInputStream zipIn= new ZipInputStream(new ByteArrayInputStream(fileArray));
                ZipEntry entry= zipIn.getNextEntry();
                dataFile= new File(entry.getName());

                byteArrayIn= new byte[1024];
                while((tempInt= zipIn.read(byteArrayIn, 0, 1024))!= -1)
                    out.write(byteArrayIn, 0, tempInt);

                zipIn.close();
                out.close();
                fileArray= by.toByteArray();
                messageSize= fileArray.length;
            }

            info.setDataFile(dataFile);
            if(dataFile.exists() && !overwrite)
            {
                message= "File Exists";
                return false;
            }

            DataOutputStream out= new DataOutputStream(new FileOutputStream(dataFile));
            out.write(fileArray, 0, fileArray.length);
            out.close();
        }
        catch(Exception e)
        {
            message= "Oops!!\n Error: "+ e;
            e.printStackTrace();
            return false;
        }

        message= "Retrieved file size: "+ messageSize+ " B";
        return true;
    }



    private static void embedBytes(byte[] bytes)
    {
        int size= bytes.length;

        for(int i=0; i< size; i++)
        {
            byte1= bytes[i];
            for(int j=8; j>=0; j-=2)
            {
                byte2= byte1;
                byte2>>= j;
                byte2&= 0x03;

                byte3= byteArrayIn[inputOutputMarker];
                byte3&= 0xFC;
                byte3|= byte2;
                byteOut.write(byte3);
                inputOutputMarker++;
            }
        }
    }


    private static void writeBytes(byte[] bytes)
    {
        int size= bytes.length;

        for(int i=0; i< size; i++)
        {
            byteOut.write(bytes[i]);
            inputOutputMarker++;
        }
    }


    private static void retrieveBytes(byte[] bytes)
    {
        int size= bytes.length;

        for(int i=0; i< size; i++)
        {
            byte1= 0;
            for(int j=8; j>=0; j-=2)
            {
                byte2= byteArrayIn[inputOutputMarker];
                inputOutputMarker++;

                byte2&= 0x03;
                byte2<<= j;
                byte1|= byte2;
            }
            bytes[i]= byte1;
        }
    }


    private static void readBytes(byte[] bytes)
    {
        int size= bytes.length;

        for(int i=0; i< size; i++)
        {
            bytes[i]= byteArrayIn[inputOutputMarker];
            inputOutputMarker++;
        }
    }


}



class SteganoInformation
{
    private File file;
    private File dataFile= null;
    private String checker;
    //private String version;
    private byte features;
    private short compressionRatio;
    private int dataLength, temp;
    private boolean isEster= false;

    private byte byteArray[], name[], byte1, byte2;
    private int inputMarker, i, j;


    public File getFile() { return file; }
    public int getInputMarker() { return inputMarker; }
    public File getDataFile() { return dataFile; }
    //public String getVersion() { return version; }
    public byte   getFeatures() { return features; }
    public short getCompressionRatio() { return compressionRatio; }
    public int   getDataLength()    { return dataLength; }
    public boolean  isEster()       { return isEster; }


    public void setDataFile(File dataFile)
    {
        this.dataFile= dataFile;
    }
    private void retrieveBytes(byte[] bytes, byte[] array, int marker)
    {
        byteArray= array;
        inputMarker= marker;

        int size= bytes.length;

        for(i=0; i< size; i++)
        {
            byte1= 0;
            for(j=8; j>=0; j-=2)
            {
                byte2= byteArray[inputMarker];
                inputMarker++;

                byte2&= 0x03;
                byte2<<= j;
                byte1|= byte2;
            }
            bytes[i]= byte1;
        }
    }

    private void retrieveBytes(byte[] bytes)
    {
        int size= bytes.length;

        for(i=0; i< size; i++)
        {
            byte1= 0;
            for(j=8; j>=0; j-=2)
            {
                byte2= byteArray[inputMarker];
                inputMarker++;

                byte2&= 0x03;
                byte2<<= j;
                byte1|= byte2;
            }
            bytes[i]= byte1;
        }
    }

    private void readBytes(byte[] bytes, byte[] array, int marker)
    {
        byteArray= array;
        inputMarker= marker;

        int size= bytes.length;

        for(i=0; i< size; i++)
        {
            bytes[i]= byteArray[inputMarker];
            inputMarker++;
        }
    }

    private void readBytes(byte[] bytes)
    {
        int size= bytes.length;

        for(i=0; i< size; i++)
        {
            bytes[i]= byteArray[inputMarker];
            inputMarker++;
        }
    }

    public static char[] byteToCharArray(byte[] bytes)
    {
        int size= bytes.length, i;
        char []chars= new char[size];
        for(i=0; i<size; i++)
        {
            bytes[i]&= 0x7F;
            chars[i]= (char) bytes[i];
        }
        return chars;
    }

    public SteganoInformation(File file)
    {
        this.file= file;
        isEster= false;

        if(!file.exists())
        {
            checker= null;
            return;
        }

        if(file.getName().equals("Sec#x&y"))
        {
            isEster= true;
            return;
        }

        byteArray= new byte[(int) file.length()];
        try
        {
            DataInputStream in= new DataInputStream(new FileInputStream(file));
            in.read(byteArray, 0, (int) file.length());
            in.close();
        }
        catch(Exception e)
        {
            checker= null;
            return;
        }


        name= new byte[4];

        String fileName= file.getName();
        String fileExtension= fileName.substring(fileName.length()-3, fileName.length());

        if(fileExtension.equalsIgnoreCase("jpg"))
            inputMarker= VideoSteganography.OFFSET_JPG;
        else if(fileExtension.equalsIgnoreCase("png"))
                inputMarker= VideoSteganography.OFFSET_PNG;
              else
                inputMarker= VideoSteganography.OFFSET_GIF_BMP_TIF;

        retrieveBytes(name, byteArray, inputMarker);
        dataLength= 0;
        for(i=24,j=0; i>=0; i-=8,j++)
        {
            temp= name[j];
            temp&= 0x000000FF;
            temp<<= i;
            dataLength|= temp;
        }
        inputMarker= dataLength;

        if(dataLength<0 || dataLength>file.length())
        {
            checker= "Invalid";
            return;
        }
        else
            checker= "EXISTS";


        /*byte versionArray[]= new byte[3];
        readBytes(versionArray, byteArray, inputMarker);
        char []versionTemp= byteToCharArray(versionArray);
        char []ver= new char[5];
        for(i=0, j=0; i<5; i++)
            if(i== 1 || i== 3)  ver[i]= '.';
            else
            {
                ver[i]= versionTemp[j++];
            }

        version= new String(ver);*/


        name= new byte[1];
        readBytes(name);
        features= name[0];


        readBytes(name);
        name[0]&= 0x7F;
        compressionRatio= name[0];


        name= new byte[4];
        readBytes(name);
        dataLength= 0;
        for(i=24,j=0; i>=0; i-=8,j++)
        {
            temp= name[j];
            temp&= 0x000000FF;
            temp<<= i;
            dataLength|= temp;
        }
    }

    public boolean isValid()
    {
        if(checker.equals("EXISTS"))
        {
            return true;
        }
        else
            return false;
    }
}




Is This A Good Question/Topic? 0
  • +

Replies To: Video Steganography

#2 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2016
  • View blog
  • Posts: 3,043
  • Joined: 21-June 11

Re: Video Steganography

Posted 03 March 2012 - 12:25 AM

The LSB part is happening here:

byte2= byte1;
byte2>>= j;
byte2&= 0x03;

byte3= byteArrayIn[inputOutputMarker];
byte3&= 0xFC;
byte3|= byte2;
byteOut.write(byte3);


The first three lines set byte2 to the jth and (j+1)th bits of byte1. So byte2 is a number between 0 and 3 (i.e. only its 2 least significant bits can be set). Line 6 clears the two least significant bits of byte3 and line 7 then sets them to the value of byte2.

This post has been edited by sepp2k: 03 March 2012 - 05:45 AM

Was This Post Helpful? 1
  • +
  • -

#3 sav10  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 17-August 11

Re: Video Steganography

Posted 03 March 2012 - 05:38 AM

When i was browsing for this code,i found that the value of j is 6.why is j initialized to 6 in the begining and why it must be decremented by 2.
private static void embedbytes(byte[] bytes)
    {
        int size= bytes.length;

        for(int i=0; i< size; i++)
        {
            byte1= bytes[i];
            for(int j=6; j>=0; j-=2)
            {
                byte2= byte1;
                byte2>>= j;
                byte2&= 0x03;

                byte3= bytearrayin[inputoutputmarker];
                byte3&= 0xfc;
                byte3|= byte2;
                byteout.write(byte3);
                inputoutputmarker++;
            }
        }
    }


Was This Post Helpful? 0
  • +
  • -

#4 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2016
  • View blog
  • Posts: 3,043
  • Joined: 21-June 11

Re: Video Steganography

Posted 03 March 2012 - 05:47 AM

It iterates by two because I didn't read carefully before and it in fact takes 2 bits at a time not one (i.e. it uses the two least significant bits for storage, not just the least significant one). It counts downwards instead of upwards, so that the first byte of the data will contain the first 2 bits, the second byte will contain the second two bits etc.
Was This Post Helpful? 0
  • +
  • -

#5 nishaan  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 3
  • Joined: 26-April 12

Re: Video Steganography

Posted 26 April 2012 - 03:43 AM

View Postsepp2k, on 03 March 2012 - 05:47 AM, said:

It iterates by two because I didn't read carefully before and it in fact takes 2 bits at a time not one (i.e. it uses the two least significant bits for storage, not just the least significant one). It counts downwards instead of upwards, so that the first byte of the data will contain the first 2 bits, the second byte will contain the second two bits etc.


Evan am doing project on Video steganography.Is it the correct way to do steganography like the above mentioned code.Here they are converting into bytes and not working on frames.I hope what am thinking is correct.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1