.TH pnmstega 1 "3 March 1994" .IX pnmstega .SH NAME pnmstega - insert a steganographic message into a portable anymap .SH SYNOPSIS .B pnmstega .RB [ -[no]length ] .RB [ -seed .IR n ] .RB [ -components .IR rgb ] .I file .RI [ pnmfile ] .SH DESCRIPTION Reads a portable anymap as input. Hides another file within the anymap by changing the low-order bits of the image's pixels, and writes the modified anymap to standard output. .PP Steganography means "hidden writing" - it's for storing a message in such a way that an opponent won't even be sure that the message is there, let alone be able to extract, decrypt, and read it. .B Pnmstega lets you store a file in the low-order bits of a PPM or PGM image. For a typical maxval of 255, this means the pixel values will be changed by only 1/256, which should not be noticable to someone viewing the image. The file you store should probably be encrypted - storing plaintext in an image is not very secure. .PP Only PGM and PPM images may be used - trying to hide a file in a PBM image would be easily visible, so it's not allowed. .SH OPTIONS The program has three flags that let you specify variations on exactly how the bits are hidden in the image. If you don't specify any flags, the default options give you a reasonable storage method, to wit: .nf -nolength -seed 0 -components rgb .fi Letting the options default like this has the advantage that you can send a stegoed image to someone without having to specify what flags you used. You can also put the file on a public FTP server for people to retrieve, without needing any other communication. However, there is a disadvantage: people who the file is not intended for will be able to extract it too. If the resulting file is recognizable in some way, for instance if it's encrypted by PGP, then the purpose of the steganographic storage will have been compromised. (A PGP file has a standard header and stores, in cleartext, the keyid needed to decrypt a file.) .PP So, if you want the file to be better hidden, you can use non-default settings for the options, in particular for the seed. Just don't forget what settings you used, and remember that if you want to send the file to someone else you will have to communicate the necessary settings somehow. .PP Or, if you're certain that the file you're hiding has no recognizable headers and has random bit statistics, for instance if you're using .I Stealth PGP, then go ahead and use the default seed. Unintended recipients will be able to extract the file correctly, but they won't be able to tell whether it's data or random noise. .PP Now, as for what the options do: .TP 12 .B -[no]length Specifies whether to prepend the file with a 32-bit length field. The default is -nolength. That means that then when someone extracts the file using .B pnmdestega it will be padded on the end with extra data, out to the size of the image. For many applications that's not a problem; for instance, if the file you're hiding is encrypted by PGP, the extra data will just be ignored. But if extra data is undesireable, you can specify -length to the length field. The disadvantage is, the length field is recognizable, since it's mostly zeros. So if you use a length field, you should hide it by using a non-default seed. .TP 12 .B -seed Specifies a seed for a pseudo-random number generator. This generator is used to make a .I permutation of the available bit positions in the image, and then the bits of the file are stored in the permuted order. Any 31-bit positive number can be used. The default is 0, which actually means don't use a permutation at all. If you use the default seed then anyone will be able to extract the file, so be sure that's ok. .TP 12 .B -components This lets you specify which of the red, green, or blue color components is used for storing bits. You give it a string made up from one or more of the letters .BR r , .BR g , and .BR b . The default is .BR rgb , use all three components. If the input image is a PGM file, instead of PPM, this option is silently ignored. .SH "COLORMAPPED FILES" You probably should not try to store a stegoed image in a colormapped file format. This is because the quantization process makes the low-order bits fairly non-random, so if you replace some of those bits with random-looking hidden data then unintended recipients might be able to tell that data is present. That would be bad. However, if you want to use a colormapped format, you can, with a little tweaking. .PP Normally to store an image in a colormapped file format such as GIF, you first run it through .BR ppmquant . However, if you try to quantize, then stega, and then convert to GIF, you will find that the .B pnmtogif step will fail with an error about too many colors. This is because the stega step increased the number of colors. You might think, ok, stega first, then quantize; nope, the quantization would destroy the steganographic message. Here's what you do instead: quantize down to .I half the number of colors you want in the final file, and then use only one of the three color components to store the hidden file. Using only one bit per pixel, the number of colors can at most double. So, the pipeline to use is: .nf ppmquant 128 image.ppm | pnmstega -comp r message.txt | pnmtogif > hidden.gif .fi Use red instead of green or blue because most pictures have a large red component, so there will likely be more different red values to hide your data among. .SH "LOSSY COMPRESSION" Don't use it. If you JPEG-compress a stega image, the hidden data will be lost. If your JPEG encoder implements the lossless mode, you can use that and it should give fairly good compression. PNG does lossless compression, so that's a good format for stega images. Otherwise you might try .IR compress or .IR gzip , plain old file compression on the PPM or PGM file. .PP Note that there is a similar steganography program called .I jsteg that does hide data in JPEG files. It does this very cleverly, putting the bits not in the color components but in the post-transformation, pre-compression color coefficients. A very interesting idea, but dependent on the specifics of JPEG. .SH "SECURITY SUMMARY" If the file you're hiding is not recognizable by itself, for instance if it's encrypted by Stealth PGP, then you're safe using the default settings. This is the most secure way to use .IR pnmstega . .PP If you can't do that, if you must hide a file that is recognizable, then use the .B -seed flag. However, be warned that the pseudo-random number generator used is not "cryptographically strong" - it's a combination of a linear congruential generator and a feedback shift register, and the former is known to be breakable. Also, the 31-bit seed size is fairly small for modern cryptographic applications. .PP If you do use the .B -seed flag, you might as well also use the .B -length flag. It won't add any significant extra exposure. .PP And again, avoid using colormapped file formats if you can. .SH "SEE ALSO" pnmdestega(1), pbmplus(1) .SH AUTHOR Copyright (C) 1994 by Jef Poskanzer. .\" Permission to use, copy, modify, and distribute this software and its .\" documentation for any purpose and without fee is hereby granted, provided .\" that the above copyright notice appear in all copies and that both that .\" copyright notice and this permission notice appear in supporting .\" documentation. This software is provided "as is" without express or .\" implied warranty.