Max Hernandez

Laberinto - Ejemplo de Canvas en HTML5

jueves, 1 de noviembre de 2012

Steganography

For this week in the information security and cryptography class we talk about the steganography, that is defined as the science or art of writing secret messages over an insecure channel in my case save the source code hidden on images of Lolcats. The principal characteristic of this science is that no one except the sender and intended recipient suspects about the existence of this message.

[image obtained from: "http://prismakhas.com/wp-content/uploads/steganography.jpg"]

My implementation
this week i made another python script, to hide the message in pictures i chose the LBS method borrowing the two least significant bits of some pixel colors to hide part of a ASCII character on them.

The hexadecimal representation of a color is a representation where every two hexadecimal numbers represent a intensity of the RGB colors Red, Green and Blue. Alternating the intensity of this colors we can obtain a complete set of most important colors.



[Image obtained from:"http://www.leapcms.com/images/hex-colours.jpg"]

To hide a single character on ASCII representation the i need at least eight bits because exist 128 characters on ASCII characters so i take the next seven bits of the hexadecimal color transformed to binary number where the bits with "1" are the borrowed bits.

     RED      GREEN     BLUE
00000111 00000011 00000011


It works because the change of these bits for a bits of a different characthers representation is imperceptible to the human eye.

The next image is one of the three lolcats with a hidden message and shows the noise of the least two bits of the red color. As we see there is a lot of noise and there is no easy way to notice patterns in the pixel shades.



My code

Enlace para descargar
http://dl.dropbox.com/u/20770926/image.py

Comando para esconder mensaje en imagen en linux

python image.py -mix nombre_imagen.png archivo_de_entrada.txt

Comando para separar mensaje de imagen en linux

python image.py -separate nombre_imagen.png archivo_de_salida.txt

Image.py
#!/usr/bin/python
from PIL import Image
import sys

image = []

def bin_text(n, digits):
    temp = bin(n)[2:]
    for i in range(digits-len(temp)):
        temp = "0" + temp
    return temp

def break_char(c):#char
    total_bits = 7

    c = bin(ord(c))[2:]
    for i in range(total_bits-len(c)):
        c = "0"+c
    return [c[:3], c[3:5],c[5:]]

def build_char(c):
    return chr(int(c,2))

def get_data(datafile):
    fl = open(datafile, "r")
    data = fl.read()
    fl.close()

    temp = []
    for i in data:
        temp.append(break_char(i))

    return temp

def mix_data(colors, data):
        R = (colors[0]&int( ("11111000"), 2))
        R = (R|int( (data[0]), 2))

        G = (colors[1]&int( ("11111001"), 2))
        G = (G|int( (data[1]+"0"), 2))

        B = (colors[2]&int( ("11111001"), 2))
        B = (B|int( (data[2]+"0"), 2))

        return (R, G, B)

def merge(picture, datafile):

    print "Abierndo archivo..."
    data = get_data(datafile)

    print "Abriendo imagen..."
    image = Image.open(picture)
    pic = image.load()

    total_pixel = image.size[0]*image.size[1]

    if (total_pixel) < len(data):
        print "Archivo demasiado grande para la imagen"
        sys.exit(0)

    len_data = bin_text(len(data), 21)

    len_data = [ [len_data[:3], len_data[3:5],len_data[5:7]], [len_data[7:10], len_data[10:12],len_data[12:14]], [len_data[14:17], len_data[17:19],len_data[19:]] ] 

    for h in range(3):
        i = h%image.size[0]
        j = int(h/image.size[0])
        pic[i,j] = mix_data(pic[i,j], len_data[h])


    print "Anadiendo ", len(data), "caracteres..."
    for h in range(3, len(data)):
        
        position = ( (3*(len(data)+h+(total_pixel%100))) + 4 )% total_pixel

        i = position%image.size[0]
        j = int(position/image.size[0])

        pic[i,j] = mix_data(pic[i,j], data[h])

    image.save(r"modified_"+picture+".bmp", "BMP")
    print "Datos agregados a la imagen."

def separate(picture, outputFile="output"):
    print "Abriendo imagen..."
    image = Image.open(picture)
    pic = image.load()

    total_pixel = image.size[0]*image.size[1]

    fl = open(outputFile,"w")

    len_fl = ""
    for h in range(3):
        i = h%image.size[0]
        j = int(h/image.size[0])

        (R, G, B) = pic[i,j]
        R = bin_text(R, 8)
        G = bin_text(G, 8)
        B = bin_text(B, 8)
        len_fl += R[5:]+G[5:7]+B[5:7]

    len_fl = int(len_fl, 2)

    print "Obteniendo ", len_fl, " caracteres..."
    for h in range(3, len_fl):
        position = ( (3*(len_fl+h+(total_pixel%100))) + 4 )% total_pixel

        i = position%image.size[0]
        j = int(position/image.size[0])

        (R, G, B) = pic[i,j]

        R = bin_text(R, 8)
        G = bin_text(G, 8)
        B = bin_text(B, 8)

        char = chr(int(R[5:]+G[5:7]+B[5:7] , 2))
        fl.write( char)

    fl.close()
    print "Caracteres obtenidos"
    

def main():
    if len(sys.argv) > 0:
        if sys.argv[1] == "-mix":
            # Nombre de la imagen, nombre del archivo a mezclar
            merge(sys.argv[2], sys.argv[3])
        elif sys.argv[1] == "-separate":
            separate(sys.argv[2], sys.argv[3])

main()

The Result
Next this are the three images with the source code shown above hidden in it's pixels hiding it using the same code.

Original image 01

[image obtained from:"http://www.netlingo.com/imagearchive/5338_lolcat_word_large.jpg"]

Same image with hidden message


Original image 05

[image obtained from:"http://www.myspacefx.net/graphics/cat/Funny_Graphics_and_Pics/lol-cats_gheck-out-my-guns.jpg"]

Same image with hidden message


Original image 06

[image obtained from:"http://images.sodahead.com/polls/000445149/polls_lol_cats_2_final_4936_632409_poll_xlarge.jpeg"]

Same image with hidden message
 

The other original images were obtain from this links
http://stuffpoint.com/lol-cats/image/28755-lol-cats-ikea-cat.jpg
http://legacy-cdn.smosh.com/smosh-pit/122010/lolcat-dumbledore-is-gay.jpg
https://i.chzbgr.com/completestore/12/10/19/fOLZEL9Z_UWpweSNH_gIMQ2.png


And for last this is part of the content of the output file result of separate the hidden message of the above images to demonstrate that it works:
usr/bin/python
from PIL import Image
import sys

image = []

def bin_text(n, digits):
    temp = bin(n)[2:]
    for i in range(digits-len(temp)):
        temp = "0" + temp
    return temp

def break_char(c):#char
    total_bits = 7

    c = bin(ord(c))[2:]
    for i in range(total_bits-len(c)):
        c = "0"+c
    return [c[:3], c[3:5],c[5:]]

...

References:
http://www.strangehorizons.com/2001/20011008/steganography.shtml
http://en.wikipedia.org/wiki/Steganography
http://www.garykessler.net/library/steganography.html

1 comentario: