Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Gif steganography

by Anonymous Monk
on Aug 10, 2001 at 02:58 UTC ( [id://103703]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I've written some code that will change the low order bit in a bmp/jpg file to hide a message. this works nicely, however dosnt work in gifs... i'm guessing its because of the record structure in a gif.

What i'd like to do is write/find some code that will allow me to do the same..

i'd preferably like to re-invent the wheel, as it will give me a greater understanding on how the whole thing works, so any help on where i can find information/code is appreciated..

Replies are listed 'Best First'.
Re: Gif steganography
by tadman (Prior) on Aug 10, 2001 at 04:50 UTC
    Since GIF uses LZW compression, your bit-twiddling is damaging the data severely. It's not like a bitmap (BMP) file where there is a one-to-one correlation between bits in the file and bits on screen. In fact, a one-bit change can ruin your entire GIF from that point on. JPEG, while it employs a different compression system, is likely to suffer the same sort of damage.

    First, use PNG. It's better for your application because it can express more colors, and unlike JPEG, the compression does not destroy any data, so the image you get out is exactly what you put in. JPEG will take some liberties with your image in order to compress it, so the output may be substantially different from the input.

    So with that established, no matter what image you use, you will have to decompress it first. You can use a library like Image::Magick to do this for you. When you have this in a regular "bitmap" format, you can go to town on it, perhaps using something like vec to twiddle your bits, or any other method you can think of. When you're finished, you can pack it back up as a PNG and fire it off.

    Of course, the tricky part is finding a "sneaky" way of modifying the bitmap image.
      ahhh! i should have realised that compression bit.. now, how dumb do i feel?

      As an alternative i could then convert the gif to a jpg, however wouldnt that be reasonably expensive for a web application?..

      The reason i'm interested particularly in gifs is i have a CGI that generates a graph as a gif. What i need to be able to do is determine whether the generated graph is authentic (ie a user has not altered it..) As the website generates a reasonable amount of hits, what i cant do is store a digest anywhere..
      i figure embedding a 'fingerprint' in the graph is a reasonable method of achieving this.

      The next question is, what do i use as a message? i figure a SHA1 or MD5 digest seeded with a combination of the users name and a long, strong password, known only to administrators.

        If that's what you're trying to do, you needn't be so devious. Instead, I would suggest using a PGP-type signature and putting that in the "comment" field of the GIF file. When you validate the GIF for authenticity, you can strip the comment out and evaluate the image for integrity. The GIF comment field should be able to contain a regular signature, which is really just text.

        This way, if the image is modified, the comment signature will not check out, and since the signature is based on a private key that they don't have, they can't forge a new one. You could achieve the same thing with SHA1 or MD5 using a long and secure "passphrase" as well.

        JPEG, as I have tried to emphasise, is a very bad idea since the compression will pretty much destroy any subtle fingerprinting you do on a bit level. A more sophisticated "watermarking" technique is required in that case, and these are generally non-trivial to implement, as they often involve things like "fuzzy logic" to detect partial patterns, or to correct damage done by the JPEG compression.
Re: Gif steganography
by trantor (Chaplain) on Aug 10, 2001 at 10:20 UTC

    Pixels in a GIF image do not express colours values directly, they are indexes in a palette.

    Colours in a palette are completely unrelated to each other: you only have 256 palette entries in a common GIF so programs try to optimize it as much as possible.

    Now, if you change a pixel value from, say, 23 (binary 00010111) to 22 (binary 00010110), inverting its low order bit, you get a different palette entry of course. Even if these entries are one next to the other, they may (and often will) point to completely unrelated colours. So colour number 23 can be an electric pink while colour 22 may be navy blue.

    That's why steganography can hardly be applied to GIF images, and when a palette is involved, I think.

    -- TMTOWTDI

      interesting.. looks like i may have to read a bit more on gif structure.
Re: Gif steganography
by Ryszard (Priest) on Aug 10, 2001 at 03:13 UTC

    The above post was from a non-anon new monk, i didnt realise i wasnt logged in at the time

Re: Gif steganography
by mitd (Curate) on Aug 10, 2001 at 21:18 UTC
    if you haven't already done so check this out tons of steganography info plus code.

    Enjoy!

    mitd-Made in the Dark
    'My favourite colour appears to be grey.'

Re: Gif steganography
by beretboy (Chaplain) on Aug 10, 2001 at 05:51 UTC
    I beg you to post the code for bmp/jpg steganography.

    "Sanity is the playground of the unimaginative" -Unknown
      here is a bit of code that will handle the swapping part..
      sub swap { my ($filechar, $msgbit) = @_; $filechar=unpack("B8",$filechar); $filechar=~pack("B8",$filechar)=~(substr($filechar,-1,1)=$msgbit); return $filechar; }
      to hide the message i:
      1) calculate the number of bytes i'll need from the source file
      2) read the bytes into a buffer
      3) turn the hidden message into binary
      4) loop thru' the bit message and the file buffer replacing the low order bit
      5) putting the buffer back into the source file..

      reasonably easy...

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://103703]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (6)
As of 2024-04-20 00:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found