Stegman
Stegman is a small utility for safely encoding files or messages in other files using steganography.
|
This is my project for the conclusion of C programming labs in the 18L semester on the Electronics and Information Technology faculty of Warsaw Institute of Technology.
Stegman is a tool that employs cryptography and steganography to safely hide messages in various files. It can also reverse the process to extract information from a file.
The user has to specify the file in which data will be encoded, a password, and the message to hide. The hiding procedure works as follows:
0x0BADFACE
as a control value, then the compressed message.0x0BADFACE
into the target image, followed by flags specifying properties of the message, followed by hash cycle count, followed by IV, followed by salt, followed by length of encrypted message, then the encrypted message.The encoding occurs on 2 least significant bits of each color component of each pixel in the target PNG image. So assuming ARGB32-encoded image, it takes 4 channels to encode 1 byte (4 x 2 bits = 8 bits = 1 byte). Thus for ARGB32 images, the final (compressed + encrypted) message can be width * height - 4 - 4 - 2 - 16 - 16 - 8
bytes long. This is because:
0x0BADFACE
is a 32-bit integer (4 bytes), used as magic value to determine whether any data is present at all.The length encoded is without padding. AES-256 encrypts data in 128-bit (16-byte) blocks. This means the encrypted message length will be rounded up to nearby 16. Knowing that, we can encode the length without padding, because we can easily calculate the length of the padded message.
The user has to specify the PNG file containing a hidden message, and password to decrypt it. The program then attempts to find, identify, and extract the message. If the input message was a file, the user has to specify the output file name. The procedure works as follows:
0x0BADFACE
. If they don't, the user is notified that the file does not contain a message and the program exits.0x0BADFACE
, the user is notified that the password they supplied is invalid, and the program exits.The 32-bit properties bitfield contains information about the source message. Descriptions of specific bits can be found below:
**Bit** | Value | Description |
---|---|---|
0 | 0x00000001 | The input message was a file |
The program was designed to work under GNU/Linux environments. It might work under other POSIX-compatible systems, provided appropriate prerequisites are installed, however that is not guaranteed. Furthermore the program was not tested under Windows at all.
Under Debian 10 (Buster) all requirements can be installed by doing:
Then you can simply clone this repository, and in its root directory, run CC=clang-6.0 CFLAGS="-O2 -march=native" LDFLAGS=-fuse-ld=lld ./config.sh && make
Any modern GNU/Linux distribution. The program was written for Debian 10 (Buster), and tester under Debian 9 (Stretch).
Any POSIX-compatible UNIX (such as FreeBSD) might also work.
The program was tested to compile with Clang 6.0, and linked with LLD 6.0. However, any C99-capable compiler should do the job.
To build the program, you need a Make implementation available on your system. The program was tested with GNU Make.
The configuration script uses Bashisms extensively, so you need a modern version of Bash installed.
Using the program is fairly straightforward. It has 2 operation modes: encode and decode.
In below descriptions, <>
indicates a required argument, []
indicates an optional one. Do not put the brackets in actual command invocation. E.g. for invocation like ./test <arg1> <arg2>
you would invoke as ./test "asdf" 123
.
To encode a message (or a file) into a file, run the program as:
./stegman encode <password> <target file> <message>
to encode a text message, or ./stegman encode <password> <target file> @<source file>
to encode a file.
**Argument** | Description |
---|---|
password | The password to secure your data before encoding. |
target file | The file in which the data will be encoded. |
message | Text message to encode in the file. |
source file | File to encode in the file. |
To decode a message from a file, you would run the program as ./stegman decode <password> <source file> [target file]
. Note that if source message was a file, you must specify target file.
**Argument** | Description |
---|---|
password | The password used to secure your encoded data. |
source file | The file in which the data was encoded. |
target file | The file in which the decoded data will be placed. |
The program and the source are shared under MIT License. See LICENSE file for details.