Skip to content

aleksbelic/ghostveil

Repository files navigation

GhostVeil

Python steganography tool for injecting a secret message into custom image.

Requirements

  • Python 3.10+

How it works

GhostVeil uses LSB (Least Significant Bit) steganography to hide a message inside an image without any visible changes to the image.

Encoding

Each pixel in a PNG image is made of 4 channels: Red, Green, Blue, and Alpha. Each channel is stored as a number from 0 to 255.

GhostVeil replaces the least significant bit of the R, G, and B channels of each pixel with a bit from the secret message. Changing only the last bit shifts the color value by at most 1, which is completely invisible to the human eye.

Before the message itself, GhostVeil writes a header into the first 4 pixels (12 bits) that stores the length of the message in bits. This allows the decoder to know exactly how many bits to read.

Pixel 1-4:   [ header  ] — stores message length (12 bits)
Pixel 5+:    [ message ] — stores message bits (3 bits per pixel)

Decoding

GhostVeil reads the least significant bit of the R, G, and B channels of each pixel. It first reads the header from the first 4 pixels to determine the message length, then reads exactly that many bits from the remaining pixels and converts them back to text.

Limits

  • Maximum message length: 511 characters
  • Minimum image size: 5 pixels (4 header + at least 1 message pixel)
  • Only lossless image formats are supported (e.g. PNG)

Install dependencies

Please check requirements.txt & requirements-dev.txt for exact versions.

Runtime dependencies:

pip install -r requirements.txt

Dev tools:

pip install -r requirements-dev.txt

Usage

⚠️ Only lossless image formats are supported (e.g. PNG). Lossy formats like JPEG will corrupt the hidden message.

Usage in console

⚠️ Encode & decode functions are non-verbose by default to make piping possible.

Encode message into image:

python3 ghostveil.py encode "Memento mori" demo.png demo_output.png

ℹ️ Output image path is optional and by default will be generated in the same directory as input image with _ghostveil suffix:

python3 ghostveil.py encode "Memento mori" demo.png
# Output: demo_ghostveil.png

Decode message from image:

python3 ghostveil.py decode demo_output.png

Using in pipeline:

python3 ghostveil.py decode demo_output.png > secret_message.txt

To make process verbose, please use flag -v or --verbose.

Verbose encoding into message:

python3 ghostveil.py -v encode "Memento mori" demo.png demo_output.png
# Encoding complete! 👻
# Output: demo_output.png

Verbose decode message from image:

python3 ghostveil.py -v decode demo_output.png
# Decoding complete! 👻
# Decoded message: Memento mori

More info:

python3 ghostveil.py -h
python3 ghostveil.py encode -h
python3 ghostveil.py decode -h

Usage in Python script

from ghostveil import encode, decode

# Encode message into image
encode("Memento mori", img_path="demo.png", output_path="demo_output.png")

# Decode message from image
message = decode("demo_output.png")
print(message)  # Memento mori

ℹ️ Output image path is optional and by default will be generated in the same directory as input image with _ghostveil suffix:

encode("Memento mori", img_path="demo.png")
message = decode("demo_ghostveil.png")
print(message)  # Memento mori

DEV Scripts

Typo check:

codespell .

Lint check:

ruff check .

Lint check with fix:

ruff check . --fix

Format code:

ruff format .

Run unit tests:

pytest

Run all scripts (lint check with fix & format & tests - requires make installed on your system):

make all

About

Python steganography tool.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors