Skip to main content

A flexible steganography and steganalysis library supporting various file types, including encryption and compression

Project description

Stegosphere

A flexible steganography and steganalysis library for image, audio, ttf, multiple file and all NumPy-array-readable steganography, including encryption and compression.

It is meant to be usable for research by combining steganography and steganalysis, see Research toolbox.

Table of contents

  1. General usage
  2. Installation
  3. Image steganography
  4. Audio steganography
  5. ttf steganography
  6. wavelet transform
  7. Multifile steganography
  8. File handling
  9. Compression and Encryption
  10. Research toolbox
  11. Contributing

General

The library is made to allow for generalisation and compatability of different steganographical methods across file types. The base steganography functions define steganography on top of numpy arrays, while the implementations for different file types primarily aid in converting between the file type and numpy arrays.

Currently, methods for image, audio, ttf, video and multi-file steganography are implemented.

Any file types which can be read as or converted to a numpy array can be used for some of the steganographic methods, which are implemented in the methods folder.

Installation

Install using pip: pip install stegosphere.

The only requirement is numpy. The file containers work with PIL for images, fontTools for ttf and cv2 for videos, however the file containers are not required to be used as they only provide the binding between files and numpy arrays.

Image steganography

For image steganography, LSB (Least Significant Bit), PVD (Pixel Value Differencing), BPCS (Bit-Plane Complexity Segmentation) and IWT (Integer Wavelet Transform) steganography are currently available.

The example loads an image into a container and writes a payload into the pixels and then reads it out again.

from stegosphere.containers.image import ImageContainer
from stegosphere.methods import LSB
from stegosphere.io import *

img = ImageContainer('image.png')
px = img.read()
cover = LSB.embed(px, 'Embedded message!', method='delimiter')
img.flush(cover)
img.save('image_stego.png')

steg_img = ImageContainer('image_stego.png')
steg_px = steg_img.read()
uncover = LSB.extract(steg_px, method='delimiter')

print(binary_to_data(uncover))
#Expected output: 'Embedded message!'

Audio steganography

For audio steganography, LSB (Least Significant Bit), FVD (Frequency Value Differencing) and IWT (Integer Wavelet Transform) steganography are currently available. The example below loads an audio and encodes the file image.png into the audio. The image is then recovered and saved.

from stegosphere.containers.audio import WAVContainer
from stegosphere.methods import VD
from stegosphere.io import file_to_binary, binary_to_file


wav = WAVContainer('audio.wav')
bin_image = file_to_binary('image.png')
frames = wav.read()
embedded = VD.embed(frames, bin_image)
wav.flush(embedded)
wav.save('steg_audio.wav')


steg_wav = WAVContainer('steg_audio.wav')
steg_frames = steg_wav.read()
extracted = VD.extract(steg_frames)

binary_to_file(extracted,'recovered_image.png')

For additional parameters, see the chapter on parameters.

ttf steganography

For ttf steganography, LSB (Least Significant Bit) and Custom Table steganography are currently available.

The example below stores a string into a custom created table within the TTF file.

from stegosphere.containers.ttf import TTFContainer
from stegosphere.methods import ttf_CustomTable


font = TTFContainer('font.ttf')

embedded = ttf_CustomTable.embed(font, 'Encoded message!', table_name='STEG')
embedded.save('steg_font.ttf')

steg_font = TTFContainer('steg_font.ttf')

print(ttf_CustomTable.extract(steg_font, 'STEG'))

wavelet transform

Integer Wavelet Transform is also available. As it is not a steganography on its own, it needs to be combined with other techniques. In this example, IWT is applied to a RGB image and the high frequency coefficients in the diagonal direction are used for LSB.

from stegosphere.containers.image import ImageContainer
from stegosphere.methods import LSB, IWT
from stegosphere.io import *

img = ImageContainer('image.png')
px = img.read()
iwt_px, meta = IWT.transform(px, skip_last_axis=True)
hf = iwt_px[('1','1')]

cover = LSB.embed(hf, 'Embedded message!', method='delimiter', seed=42)

iwt_px[('1','1')] = cover
#transform pixels back into spatial domain
px_embed = IWT.inverse(iwt_px, meta)
img.flush(px_embed)
img.save('stego.png')
#extracing
steg_img = ImageContainer('stego.png')
steg_px = steg_img.read()
iwt, _ = IWT.transform(steg_px, skip_last_axis=True)
data = iwt[('1','1')]
uncover = LSB.extract(data, method='delimiter', seed=42)

print(binary_to_data(uncover))
#Expected output: 'Embedded message!'

Multifile steganography

It is also possible to divide the payload across different files. Different methods and parameters can be used for each file where data is being encoded. Below, the content of the file payload.png is distributed randomly (with a seed) across the files image.png and audio.wav, with LSB and FVD being used.

from stegosphere.containers import image, audio
from stegosphere.methods import LSB, VD
from stegosphere.tools import multifile
from stegosphere import io

data = io.file_to_binary('payload.png')

img = image.ImageContainer('image.png')
aud = audio.WAVContainer('audio.wav')

px = img.read()
frames = aud.read()

img_encode = lambda payload: LSB.embed(px, payload)
aud_encode = lambda payload: VD.embed(frames, payload)

#the encoded image pixels and audio frames
IMG, AUD = multifile.split_encode(data, [img_encode, aud_encode], seed=42)
#flush encoded data into file objects
img.flush(IMG)
aud.flush(AUD)

img.save('stego_image.png')
aud.save('stego_audio.wav')

#Extracting
img = image.ImageContainer('stego_image.png')
aud = audio.WAVContainer('stego_audio.wav')

px, frames = img.read(), aud.read()

img_extract = lambda: LSB.extract(px)
aud_extract = lambda: VD.extract(frames)

output = multifile.split_decode([img_extract, aud_extract], seed=42)

assert output == data

The payload can be distributed evenly (default setting), using weighted distribution or roundrobin.

File handling

Several functions for file handling are provided.

stegosphere.io.file_to_binary(path) --> converts any file into binary for encoding.

stegosphere.io.binary_to_file(binary_data, output_path) --> saves binary back into file format.

stegosphere.io.data_to_binary(data) --> converts any string into binary for encoding.

stegosphere.io.binary_to_data(binary) --> converts a binary string into a readable bytes object.

Compression and encryption

Additionally, compression and encryption are provided. Compression can be used by setting compress='lzma' when encoding/decoding. The given message will then be (de)compressed using lzma.

Compression can also be used on its own, by using compression.compress/compression.decompress. lzmaand deflate algorithm are currently available.

Research toolbox

The steganography and steganalysis modules can be combined to create research pipelines. Below is an example of measuring how different measures (speed, PSNR, ...) change when increasing the payload of an image, using LSB, for a set of images from a folder.

import pandas as pd

from stegosphere.methods import LSB
from stegosphere.utils import generate_binary_payload as gbp
from stegosphere.analysis import efficiency, imperceptibility, detectability, accuracy
from stegosphere.containers import ContainerCollection
from stegosphere.containers import image

import os
path = os.listdir('PATH_TO_IMAGE_DIRECTORY')

images = ContainerCollection(path, image.ImageContainer, filter=True)
pxs = images.read()

df = pd.DataFrame(columns=['image', 'capacity','psnr','embed efficiency', 'detector','accuracy','extract efficiency'])

#test for different images
for path, px in zip(images.paths, pxs):
    max_capacity = LSB.max_capacity(px) - LSB.METADATA_LENGTH_LSB
    max_payload = gbp(max_capacity)

    #test for differrent payload sizes
    for cap in range(0, max_capacity, max_capacity//10):
        #Embedding efficiency
        with efficiency.Timer() as embed_time:
            emb = LSB.embed(px, max_payload[:cap])
        #Imperceptibility
        p = imperceptibility.psnr(px, emb, 255)
        #Detectability
        d = detectability.uniformity_detector(emb)
        #Extraction efficiency
        with efficiency.Timer() as extract_time:
            ext = LSB.extract(emb)
        #Extraction accuracy
        acc = accuracy.bit_error_rate(ext, max_payload[:cap])
        #Store results
        df.loc[len(df)] = path, cap, p , embed_time.diff, d, acc, extract_time.diff

print(df)

Contributing

Any support or input is always welcomed. Additional general methods are much needed.

Contact:

Email: maximilian.koch@student.uva.nl

LinkedIn: https://www.linkedin.com/in/maximilian-jw-koch/

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

stegosphere-1.2.2.tar.gz (65.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

stegosphere-1.2.2-py3-none-any.whl (68.7 kB view details)

Uploaded Python 3

File details

Details for the file stegosphere-1.2.2.tar.gz.

File metadata

  • Download URL: stegosphere-1.2.2.tar.gz
  • Upload date:
  • Size: 65.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.6

File hashes

Hashes for stegosphere-1.2.2.tar.gz
Algorithm Hash digest
SHA256 ae3b1336860dc30bcd2c815db06f07a264fc383aa09d428c02e0e377dbfb229a
MD5 8cc2a8cdabe16478c62e0ef94e8416de
BLAKE2b-256 9ff53eeedcbe269e425d2345b179fb87bca0361f96d5ca6c4f1dbee03a798931

See more details on using hashes here.

File details

Details for the file stegosphere-1.2.2-py3-none-any.whl.

File metadata

  • Download URL: stegosphere-1.2.2-py3-none-any.whl
  • Upload date:
  • Size: 68.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.6

File hashes

Hashes for stegosphere-1.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 db4bf1c95d36f04f7349cec771b86e819454c09a18d34d8642b6f8abc960eebe
MD5 db6083f66852a4bd1b4af59fef3090d6
BLAKE2b-256 a6b641f1d8b9c129b1acdc13ad4ba5b48daf08a762361c2ef9c65eff29a17c76

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page