Could someone help for a final group project about steganography

Hello, i'm a member of a 3 person group, we are in 12th Grade in France and we have the project to create a programme in processing which would encrypt an imported image and decrypt it on demand using the steganography process.

We made 3 programmes:

The first programme import an image and show it to the user and it encrypts it and make a mask. (the encrypted image + XOR + the mask = the imported image)

the second programme we made is about encrypting the image imported

and the third programme is about decrypting the encrypted image.

The problem we have is that, because of our poor english and java skills we can't put the 3 programmes in one...

Tagged:

Answers

  • edited May 2016

    The program which decrypt is this one

    //image chiffrée = masque xor image secrète

    PImage imgA,imgB, imgC; //A=masque, B=image chiffrée, C=image secrète int display; int nbPixels; int[] tabA, tabB, tabC; color bl, wh;

    void setup() { size(600,600); imgA = loadImage("A.png"); imgB = loadImage("B.png");

    nbPixels=imgA.height*imgA.width; tabA=new int[nbPixels]; tabB=new int[nbPixels]; tabC=new int[nbPixels];
    bl=color(0); wh=color(255);

    AnalyseImgA();

    AnalyseImgB();

    decryptage(); display=3; }

    void draw() { if (display==3) { imageC(); image(imgC,0,0); } }

    void AnalyseImgA() { imgA.loadPixels();

    for (int y=0 ; y < imgA.height ; y=y+1) //loop hauteur (y) { for (int x=0 ; x < imgA.width ; x=x+1) //loop largeur (x) { color c = imgA.get(x,y); if (c==bl) tabA[x+(yimgA.width)]=0; else tabA[x+(yimgA.width)]=1; } } }

    void AnalyseImgB() { imgB.loadPixels();

    for (int y=0 ; y < imgB.height ; y=y+1) //loop hauteur (y) { for (int x=0 ; x < imgB.width ; x=x+1) //loop largeur (x) { color c = imgB.get(x,y); if (c==bl) tabB[x+(yimgB.width)]=0; else tabB[x+(yimgB.width)]=1; } } }

    void decryptage() { for (int i=0 ; i < nbPixels ; i=i+1) { if (tabA[i]==tabB[i]) tabC[i]=0; else tabC[i]=1; } }

    void imageC() { imgC=createImage(354, 450, RGB); imgC.loadPixels();

    for(int i=0 ; i < nbPixels ; i=i+1) { if(tabC[i]==0) imgC.pixels[i]=wh; else imgC.pixels[i]=bl; }

    imgC.updatePixels(); }

  • The one which encrypt is this one

    PImage imgA,imgB, imgC; //A=masque, B=image chiffrée, C=image secrète
    int display;
    int nbPixels;
    int[] tabA, tabB, tabC;
    color bl, wh;
    
    void setup()
    {
      size(354,450);
      imgA = loadImage("A.png");
      imgC = loadImage("C.png");
    
      nbPixels=height*width;
      tabA=new int[nbPixels];  tabB=new int[nbPixels];  tabC=new int[nbPixels];  
      bl=color(0); wh=color(255);
    
      AnalyseImgA();
    
      AnalyseImgC();
    
      cryptage();
      display=3;
    }
    
    void draw() 
    {
      if (display==3)
      {
        imageB();
        image(imgB,0,0);
      }
    }
    
    void AnalyseImgA()
    {
      imgA.loadPixels();
    
     for (int y=0 ; y < height ; y=y+1) //loop hauteur (y)
      {
        for (int x=0 ; x < width ; x=x+1) //loop largeur (x)
        {
            color c = imgA.get(x,y);
            if (c==bl)
              tabA[x+(y*width)]=0;
            else
              tabA[x+(y*width)]=1;
        }
      }
    }
    
    void AnalyseImgC()
    {
      imgC.loadPixels();
    
     for (int y=0 ; y < height ; y=y+1) //loop hauteur (y)
      {
        for (int x=0 ; x < width ; x=x+1) //loop largeur (x)
        {
            color c = imgC.get(x,y);
            if (c==bl)
              tabC[x+(y*width)]=0;
            else
              tabC[x+(y*width)]=1;
        }
      }
    }
    
    void cryptage()
    {
      for (int i=0 ; i < nbPixels ; i=i+1)
      {
        if (tabA[i]==tabC[i])
          tabB[i]=1;
        else
          tabB[i]=0;
      }
    }
    
    void imageB()
    { 
      imgB=createImage(354, 450, RGB);
      imgB.loadPixels();
    
      for(int i=0 ; i < nbPixels ; i=i+1)
      {
        if(tabB[i]==1)
          imgB.pixels[i]=wh;
        else
          imgB.pixels[i]=bl;
      }
    
      imgB.updatePixels();
    }
    
  • We did this but it doesn't work and it only has the decrypting code in it..

    Button[] menuButtons;
    static final int NUMMENUBUTTONS = 3;
    int menu;
    //PImage img;
    //PImage imgmasque;
    color c;
    int value = 0;
    PImage imgA,imgB, imgC, imgSecrete; //A=masque, B=image chiffrée, C=image secrète
    int display;
    int nbPixels;
    int[] tabA, tabB, tabC;
    color bl, wh;
    
    void setup() {
      menu=0;
      size(640, 640);
      menuButtons = new Button[3];
      menuButtons[0] = new Button("Décryptage", new PVector(100, 100), 32, color(0), color(255, 0, 0));
      menuButtons[1] = new Button("afficher masque", new PVector(100, 300), 32, color(0), color(255, 0, 0));
      menuButtons[2] = new Button("retour", new PVector (50, 550), 32, color(0), color(255,0 ,0));
    
      //imgC = loadImage("C.png");
      ////img = loadImage("image.png");
      //imgA = createImage(imgC.width, imgC.height, RGB);
      //imgSecrete=createImage(354, 450, RGB);
    
      if(menu==1)
      {
        decryptage1();
        menu=2;
      }
      if (menu==3)
      {
        masque();
        menu=4;
      }
    }
    
    void masque()
    {
      imgC = loadImage("C.png");
      imgA = createImage(imgC.width, imgC.height, RGB);
      imgA.loadPixels();
    
    for (int i = 0; i < imgA.pixels.length; i++)
    {
      int rand = int(random(2));
    
      if (rand==0)
        c = color(0);
    
      if (rand==1)
        c = color(255);
    
      imgA.pixels[i] = c;
    }
    
    imgA.updatePixels();
    //image(imgA,0,0);
    //noLoop();
    //redraw();
    }
    
    
    //void afficherimgbase()
    //{
    //  background(255);
    //  image(imgC,130,100);
    //  noLoop();
    //}
    
    //void affichermasque()
    //{
    //  //background(255);
    //  masque();
    //  noLoop();
    //  redraw();
    //}
    
    
    
    void draw(){
      if (menu==0)
        {
      background(255);
      displayMenu();
        }
    
      if (menu==2)
      {
        imageSecrete();
        image(imgSecrete,0,0);
        menuButtons[2].draw();
      }
    
      if (menu==4)
      {
        //image(imgA,0,0);
        menuButtons[2].draw();
      }
    
    }
    
    void displayMenu() {
     for (int i = 0; i < NUMMENUBUTTONS; i++) {
       menuButtons[i].draw();
     }
    }
    
    void mousePressed() {
      if (menuButtons[0].containsMouse()) 
        menu=1;  
    
      if (menuButtons[1].containsMouse()) 
        menu=2;
    
      if(menuButtons[2].containsMouse())
        menu=0;
    
    }
    
    
    ///////////////////////////////////////////////////////////////////////
    
    
    void decryptage1()
    { 
    
      nbPixels=imgA.height*imgA.width;
      tabA=new int[nbPixels];  tabB=new int[nbPixels];  tabC=new int[nbPixels];  
      bl=color(0); wh=color(255);
      imgSecrete=createImage(354, 450, RGB);
      imgA = loadImage("A.png");
      imgB = loadImage("B.png");
    
      AnalyseImgA();
      AnalyseImgB();
      decryptage();
      //display=3;
    
    }
    
    
    void AnalyseImgA()
    {
      imgA.loadPixels();
    
     for (int y=0 ; y < height ; y=y+1) //loop hauteur (y)
      {
        for (int x=0 ; x < width ; x=x+1) //loop largeur (x)
        {
            color c = imgA.get(x,y);
            if (c==bl)
              tabA[x+(y*width)]=0;
            else
              tabA[x+(y*width)]=1;
        }
      }
    }
    
    
    void AnalyseImgB()
    {
      imgB.loadPixels();
    
     for (int y=0 ; y < height ; y=y+1) //loop hauteur (y)
      {
        for (int x=0 ; x < width ; x=x+1) //loop largeur (x)
        {
            color c = imgB.get(x,y);
            if (c==bl)
              tabB[x+(y*width)]=0;
            else
              tabB[x+(y*width)]=1;
        }
      }
    }
    
    void decryptage()
    {
      for (int i=0 ; i < nbPixels ; i=i+1)
      {
        if (tabA[i]==tabB[i])
          tabC[i]=0;
        else
          tabC[i]=1;
      }
    }
    
    void imageSecrete()
    { 
      imgSecrete=createImage(354, 450, RGB);
      imgSecrete.loadPixels();
    
      for(int i=0 ; i < nbPixels ; i=i+1)
      {
        if(tabC[i]==0)
          imgSecrete.pixels[i]=wh;
        else
          imgSecrete.pixels[i]=bl;
      }
    
      imgSecrete.updatePixels();
    }
    
    
    ///////////////////////////////////////////////////////
    
    
    class Button {
      PVector pos;
      color textColor, hoverColor;
      float size, tWidth;
      String text;
    
      Button(String text, PVector pos, float size, color textColor, color hoverColor) {
        this.pos = pos;
        this.textColor = textColor;
        this.hoverColor = hoverColor;
        this.size = size;
        this.text = text;
        textSize(size);
        tWidth = textWidth(text);
      }
    
      void draw() {
        textSize(size);
        if (containsMouse()) fill(hoverColor);
        else fill(textColor);
        text(text, pos.x, pos.y + size);
    
      }
    
      boolean containsMouse() {
        if (mouseX > pos.x && mouseX < pos.x + tWidth && mouseY > pos.y && mouseY < pos.y + size )
          return true;
        else return false;
      }
    }
    
  • edited May 2016

    Steganography is about hiding information in plain sight so it is not really about encryption. In fact there is a steganography library for Processing but you won't be able to use that because it is a class exercise.

    So to help discuss this I will define the two images

    burden the image to hide
    carrier the image to hide the burden in.

    The carrier image with burden should look just like the original version. Hence hiding in plain sight.

    I will call the process of putting the burden into the carrier image , encoding and the process of extracting the burden image from the carrier image, decoding

    When an image is stored in RAM , each pixel is a 32-bit integer, comprising of four 8-bit channels i.e. ARGB. This diagram shows how the channels are arranged inside the integer

    pixel0

    The four channels are

    alpha (transparency)
    red
    green
    blue

    and each channel is just a single byte e.g.

    byte0

    MSB = most significant bit LSB = least significant bit

    Steganography takes advantage of the fact that the 4 least significant bits (0-3) have virtually no visible effect on the actual colour displayed. It means that we can have any values we like in bits 0-3 without the effect being visible in the image.

    Therefore we can use up to 4 bits per channel (bpc) to store the burden image

    pixel2

    The same rule applies for the burden image so in theory the carrier and burden images can be exactly the same size but in reality they will be different so you would also need to store the width and height of the burden image in the carrier image as well as the pixel data.

    To continue this I will define some more terms

    cp[?] is a pixel from the carrier image pixel array
    bp[?] is a pixel from the burden image pixel array
    cw & ch = width and height of the carrier image bw & bh = width and height of the burden image

    So how to encode the burden image into the carrier image

    IMPORTANT: this only works if cw * ch >= bw * bh - 2 the two bytes is to store bw and bh

    Step 1
    Loop through the carrier image array zeroing the lower 4 bits with
    cp[i] = cp[i] & 0xF0F0F0F0;

    Step 2
    Loop through the burden pixel array to remove lower 4 bits and shift the high bits right
    bp[i] = (bp[i] & 0xF0F0F0F0) >>> 4;

    Step 3
    Merge the carrier and burden arrays cp[i] = cp[i] | bp[i];

    Step 4
    Store the burden image size
    cp[cw * ch -2] = bw;
    cp[cw * ch -1] = bh;

    Step 5
    Store the image as a png file. IMPORTANT the image format MUST be lossless.

    Decoding the burden is the reverse process.

    There are lots of improvements that can be made to this algorithm but I doubt whether your tutor will mind.

    I have just noticed you have posted a lot of code since I started this comment. C'est la vie

  • edited May 2016

    Hi quark and thank you !

    I read your comment but i didn't understand everything, but it wasn't really our question haha ^^'

    The fact is that we learnt javascool for only months and we have other majors in France (Mathematics, Physics/Chemistry, Biology and 4 others..) the fact is that we had only 3-4months to work on this project and we only had the time to make it work for b&w images.. the different programs themselves work but we don't know how to put them together as the 3rd program which didn't work..

    Thank you for your post, it's very interesting to read it but we didn't ask for "how steganography works" but for "how to put those programs together to make them work" sorry for my english ^^'

  • but we didn't ask for "how steganography works"

    My reply was based on your first comment above. It doesn't just explain how steganography works it also provides algorithms for encoding the steganograph which could be used to create a program.

    "how to put those programs together to make them work"

    Unfortunately you posted the code you wanted to merge 28 minutes after your first comment so I didn't notice it until I came to post the comment.

    Hopefully someone else will find the information useful :)

    Good luck with your assignment :)

Sign In or Register to comment.