So, this is basically a follow up to yesterday's post.
And the program I told you about is now on the sidebar. Of course, you'll probably need Python to run it, but that's fine. stegano.py will hide a file of your choice in a bitmap and unstegano.py will bring it back. Pretty handy.
Now, you'll notice that you can specify the quality of your steganization. This basically describes how many bits of the hidden file we hide per byte. So it ranges from 1 to 8, with 1 being very subtle (you're only altering the LSB) to 8 which is very unsubtle (the entire pixel is replaced with stuff from the hidden data). The bonus is, of course, 8 takes up 1/8 the space of 1. Even 2 takes up only half the space of 1, and looks the same to my eye. To see the difference between the qualities, here's the first two paragraphs of this post repeated 5 times hidden in Mr. Happy from yesterday at all possible quality levels:
Quality 8:
Quality 7:
Quality 6:
Quality 5:
Quality 4:
Quality 3:
Quality 2:
Quality 1:
Original (no hidden info):
It should be noted that it always takes the most significant bits from the image, so even with quality 7 (where there's only one bit from Mr. Happy) the noise is quite "see-through".
Now, how can the evil enemies detect this? Well, there are lots of advanced statistical image processing techniques they can use to see if there is something "beneath" the image. You can go google 'steganalysis' to figure out how it's actually done - I'll just show one of the most crude techniques.
First, behold the below image of some random very badly built Mechano toy that I threw into the snow today:
You'll notice it's a JPEG. That's because I'm definitely not going to upload a 1632 by 1224 bitmap image for you. Definitely not. But I did the following test with a bitmap, so no worries.
The reason, of course, that I'm not going to upload a 1632 by 1224 bitmap for you, is because bitmaps are big. While the bitmap is about 5 megabytes large, the corresponding JPEG is only 122 kb. So, a lot of space is wasted in bitmaps. And we make use of that space when we hide stuff in them.
Of course, every 1632 by 1224 bitmap file is about the same size. But, what if we try compressing them? I have a feeling a 1632 by 1224 black rectangle compresses just a bit better than the above image. Similarly, if we hide information inside bitmaps, it has to be compressed too. So hmm...
In any case, I took the Gettysburg Address (1.4 KB), the Declaration of Independence (9.1 KB), and Dickens' Great Expectations (997 KB), and hid them all (with quality 2) inside a copy of the above image. Then I zipped the resulting images. The results:
Hidden Information | Size of Hidden Info | Size of Compressed Result |
None (original picture) | 0 KB | 1646 KB |
Gettysburg Address | 1.4 KB | 1648 KB |
Declaration of Independence | 9.1 KB | 1652 KB |
Dickens' Great Expectations | 997 KB | 2168 KB |
So, you can notice a difference =).
Of course, this is a very hard test to do if you don't have an original picture, because different images compress differently. But you can generally notice if someone is trying to hide Great Expectations =).
Oh, and perhaps I didn't mention it, but of course, you can hide any type of file this way (because after all, all files are ultimately binary). Hiding Mr. Happy in:
(I know, we'd usually hide the Secret Plan in Mr. Happy, but the Secret Plan file is bigger, so stick with this), at quality 4 we'd get:
Yeah, it's noticeable but whatever. Given all the other random things happening in that picture, it doesn't look so off. If you use quality 1, 2, or 3 though usually you don't notice anything.
In any case, this was my first 'big' project in Python, which seems to be a really powerful language even though I only know about a quarter of its features. It may not be as powerful as C++, but it's probably a good choice for someone new to programming to learn.
Anyway, there are a bunch of improvements that you could probably make to the programs. The first is modularizing it and allowing to bypass the annoying input so you can do tests like the one above much more easily. Secondly, non-integer qualities would be nice too. Like, if I have lots of room, I should be able to set it to say 0.3. Since quality acts harmonically (1/n ish), there'd even be a considerable difference between 7.3 and 8. The nicest thing would be to figure out the best possible quality that takes advantage of the entire file - because only using the bottom n rows is pretty dumb. destegano should be able to figure out how large the file is by itself (although honestly, any self-respecting file type allows extra zero bytes at the end, so we could just choose the size of the steganograph). Also, it needs to be optimized a lot - hiding Great Expectations took quite a while. But for a quick hack, it's pretty nice.
If you actually bother getting it to work, have fun playing around with it and hiding files from other people. But that's all for now. Maybe next time I'll talk about laser beams or something.
Until then, ciao.
-squid out
0 comments:
Post a Comment