Steganography techniques for hiding information in images

Steganography techniques for hiding information in images

Introduction to Steganography: Hiding in Plain Sight

Steganography, derived from the Greek words “steganos” (covered) and “graphein” (to write), is the art and science of concealing information within another object. Unlike its counterpart, cryptography, which scrambles information to make it unreadable, steganography hides the presence of the message itself. It’s like whispering a secret within a bustling marketplace, hoping no one notices.

key concepts:

1. Hidden Data: This can be anything you want to keep secret: text, images, audio, video, or even code.

2. Cover Object: This is the seemingly innocuous carrier of the hidden information. It could be a digital image, video file, audio track, text document, or even a physical object like a book or painting.

3. Embedding Techniques: These are the clever ways to hide the data within the cover object. Some common techniques include:

  • Least Significant Bit (LSB) Modification: Replacing the least significant bits of pixels in an image with information bits.
  • Modulation Methods: Embedding data by slightly modifying the frequencies of audio or video signals.
  • Meta-data Manipulation: Hiding information within unused or custom fields of file formats.
  • Cover Object Replacement: Substituting seemingly insignificant parts of the cover object with encoded data.

4. Extracting Techniques: These are the methods used to retrieve the hidden information from the cover object. They depend on the specific embedding technique used, and often require knowledge of the encoding process.

5. Applications of Steganography:

  • Secure Communication: Secretly exchanging messages while avoiding detection.
  • Copyright Protection: Embedding copyright information within multimedia content.
  • Data Redundancy: Hiding additional information within existing data for disaster recovery purposes.
  • Digital Watermarking: Identifying the ownership of digital content imperceptibly.

6. Ethical Considerations:

Steganography is a powerful tool, but it comes with significant ethical considerations. Its use for illegal activities like terrorism or cybercrime must be condemned. It’s crucial to use steganography responsibly and within legal boundaries.

Steganography with LSB

Python
#!/usr/bin/env python

from PIL import Image

def set_LSB(value, bit):
    if bit == '0':
        value = value & 254
    else:
        value = value | 1
    return value

def get_LSB(value):
    if value & 1 == 0:
        return '0'
    else:
        return '1'

def get_pixel_pairs(iterable):
    a = iter(iterable)
    return zip(a, a)


def extract_message(image):
 
    c_image = Image.open(image)
    pixel_list = list(c_image.getdata())
    message = ""

    for pix1, pix2 in get_pixel_pairs(pixel_list):
        message_byte = "0b"
        for p in pix1:
            message_byte += get_LSB(p)

        for p in pix2:
            message_byte += get_LSB(p)
            
        if message_byte == "0b00000000":
            break

        message += chr(int(message_byte,2))

    return message
    
def hide_message(image, message, outfile):

    message += chr(0)
    c_image = Image.open(image)
    c_image = c_image.convert('RGBA')
    out = Image.new(c_image.mode, c_image.size)
    width, height = c_image.size
    pixList = list(c_image.getdata())
    newArray = []
    
    for i in range(len(message)):
        charInt = ord(message[i])
        cb = str(bin(charInt))[2:].zfill(8)
        pix1 = pixList[i*2]
        pix2 = pixList[(i*2)+1]
        newpix1 = []
        newpix2 = []

        for j in range(0,4):
            newpix1.append(set_LSB(pix1[j], cb[j]))
            newpix2.append(set_LSB(pix2[j], cb[j+4]))

        newArray.append(tuple(newpix1))
        newArray.append(tuple(newpix2))

    newArray.extend(pixList[len(message)*2:])
    
    out.putdata(newArray)
    out.save(outfile)
    return outfile   

	
if __name__ == "__main__":
    print("Testing hide message in python_secrets.png with LSB ...")
    print(hide_message('python.png', 'Hidden message', 'python_secrets.png'))
    print("Hide test passed, testing message extraction ...")
    print(extract_message('python_secrets.png'))

Explanation of the functions and the main code:

  1. set_LSB(value, bit) function:

    • This function takes a pixel value (value) and a bit (bit) as parameters.
    • It modifies the least significant bit of the pixel value based on the provided bit (0 or 1) and returns the updated value.
  2. get_LSB(value) function:

    • This function takes a pixel value (value) as a parameter.
    • It extracts the least significant bit from the pixel value and returns it as a string (‘0’ or ‘1’).
  3. get_pixel_pairs(iterable) function:

    • This function takes an iterable and returns an iterator that generates pairs of elements from the iterable.
    • It’s used to iterate over pairs of pixels in the image.
  4. extract_message(image) function:

    • This function extracts a hidden message from an image that was previously created using LSB steganography.
    • It opens the image, retrieves the pixel data, and iterates over pairs of pixels.
    • For each pair, it extracts the LSBs from each pixel’s color channel to reconstruct the hidden message.
    • The message is terminated when ‘00000000’ (null terminator) is encountered.
  5. hide_message(image, message, outfile) function:

    • This function hides a message in an image using LSB steganography and saves the result to an output file.
    • It opens the original image, converts it to RGBA mode, and creates a new image for the output.
    • It converts each character of the message to its binary representation and replaces the LSBs of pairs of pixels with the message bits.
    • The resulting image is saved to the specified output file.
  6. Main Code:

    • The script tests the hide_message function by hiding the message “Hidden message” in the ‘python.png’ image and saving the result as ‘python_secrets.png’.
    • It then tests the extract_message function by attempting to extract the hidden message from ‘python_secrets.png’.

Steganography with Stegano

Stegano is a versatile Python library for image steganography, offering features to hide and reveal secret messages within image files. Here’s a breakdown of its functionalities and a brief guide to get you started:

Stegano Capabilities:

  • Text Hiding: Embed plaintext messages within images using LSB (Least Significant Bit) steganography.
  • File Hiding: Conceal files of any format within images.
  • Password Protection: Encrypt hidden information with a password for added security.
  • Multiple Image Formats: Supports various image formats like PNG, JPEG, BMP, and more.
  • Command-Line Interface: Easy to use through command-line commands for encryption and decryption.

Using Stegano:

  1. Installation: Ensure you have Python and Stegano installed: pip install stegano

  2. Hiding a Message:

# Hide text message "This is a secret!" in image "photo.jpg" with password "mypassword"
stegano -e -p mypassword -m "This is a secret!" photo.jpg secret_photo.jpg
  1. Revealing the Message:
# Extract hidden message from "secret_photo.jpg" using password "mypassword"
stegano -d -p mypassword secret_photo.jpg
  1. Hiding a File:
# Hide file "secret_file.txt" in image "cover.jpg" with no password
stegano -ef cover.jpg secret_file.txt stego_image.jpg
  1. Extracting a File:
# Extract hidden file from "stego_image.jpg"
stegano -df stego_image.jpg extracted_file.txt

Additional Notes:

  • Image quality may slightly degrade after embedding data, depending on the size of the hidden information.
  • Stegano works best with larger, complex images containing more redundant data for hiding bits.
  • Consider password complexity and security practices when using password protection.
  • Remember, steganography is not a foolproof security measure. Advanced steganalysis techniques may be able to detect hidden messages.

Steganography with stepic

Stepic Crypto Features:

  • Text Hiding: Embed text messages within images using LSB (Least Significant Bit) steganography.
  • Image Hiding: Conceal smaller images within larger ones.
  • Noise Addition: Optionally add noise to the cover image to further mask the hidden data.
  • Multiple Image Formats: Supports formats like PNG, JPEG, BMP, and more.
  • API Integration: Designed for integration into Python applications and projects.
Python
from PIL import Image
import stepic

image = Image.open("python.png")
image2 = stepic.encode(image, 'This is the hidden text'.encode("utf8"))
image2.save('python_secrets.png','PNG')
image2 = Image.open('python_secrets.png')
data = stepic.decode(image2) 
print("Decoded data: " + data)
Python
# stepic - Python image steganography

from PIL import Image

def _validate_image(image):
    if image.mode not in ('RGB', 'RGBA', 'CMYK'):
        raise ValueError('Unsupported pixel format: '
                         'image must be RGB, RGBA, or CMYK')
    if image.format == 'JPEG':
        raise ValueError('JPEG format incompatible with steganography')


def encode_imdata(imdata, data):
    '''given a sequence of pixels, returns an iterator of pixels with
    encoded data'''

    datalen = len(data)
    if datalen == 0:
        raise ValueError('data is empty')
    if datalen * 3 > len(imdata):
        raise ValueError('data is too large for image')

    imdata = iter(imdata)

    for i in range(datalen):
        pixels = [value & ~1 for value in
                  imdata.__next__()[:3] + imdata.__next__()[:3] + imdata.__next__()[:3]]
        byte = data[i]
        for j in range(7, -1, -1):
            pixels[j] |= byte & 1
            byte >>= 1
        if i == datalen - 1:
            pixels[-1] |= 1
        pixels = tuple(pixels)
        yield pixels[0:3]
        yield pixels[3:6]
        yield pixels[6:9]


def encode_inplace(image, data):
    '''hides data in an image'''

    _validate_image(image)

    w = image.size[0]
    (x, y) = (0, 0)
    for pixel in encode_imdata(image.getdata(), data):
        image.putpixel((x, y), pixel)
        if x == w - 1:
            x = 0
            y += 1
        else:
            x += 1


def encode(image, data):
    '''generates an image with hidden data, starting with an existing
    image and arbitrary data'''

    image = image.copy()
    encode_inplace(image, data)
    
    # Save image
    image.save('python-secret.png')
    
    return image


def decode_imdata(imdata):
    '''Given a sequence of pixels, returns an iterator of characters
    encoded in the image'''

    imdata = iter(imdata)
    while True:
        pixels = list(imdata.__next__()[:3] + imdata.__next__()[:3] + imdata.__next__()[:3])
        byte = 0
        for c in range(7):
            byte |= pixels[c] & 1
            byte <<= 1
        byte |= pixels[7] & 1
        yield chr(byte)
        if pixels[-1] & 1:
            break


def decode(image):
    '''extracts data from an image'''

    _validate_image(image)

    return ''.join(decode_imdata(image.getdata()))


if __name__ == "__main__":
    img = Image.open('python.png')
    #encrypt message in image
    encode(img,'this is a secret message')
    #decrypt messagte in image
    img = Image.open('python-secret.png')
    text_decoded = decode(img)
    print(text_decoded)
  1. _validate_image function:

    • Validates that the image has a supported pixel format (RGB, RGBA, or CMYK).
    • Raises an exception if the image format is JPEG (incompatible with steganography).
  2. encode_imdata function:

    • Takes a sequence of pixels (imdata) and the data to be encoded.
    • Iterates over the pixel values, modifying the least significant bit (LSB) of each color channel to encode the data.
    • Yields the modified pixel values.
  3. encode_inplace function:

    • Takes an image and the data to be encoded.
    • Calls _validate_image to ensure the image is in a supported format.
    • Iterates over the image pixels, calling encode_imdata to modify the pixel values in place.
  4. encode function:

    • Takes an image and the data to be encoded.
    • Creates a copy of the image and calls encode_inplace on the copy.
    • Saves the resulting image with the hidden message as ‘python-secret.png’.
    • Returns the modified image.
  5. decode_imdata function:

    • Takes a sequence of pixels (imdata) and decodes characters from the LSB of the pixel values.
    • Yields the decoded characters until the LSB of the last pixel indicates the end of the message.
  6. decode function:

    • Takes an image and decodes the hidden message using decode_imdata.
  7. Main Code:

    • Opens the image ‘python.png’.
    • Calls encode to hide the message ‘this is a secret message’ in the image.
    • Opens the encoded image ‘python-secret.png’.
    • Calls decode to extract and print the hidden message.
Total
5
Shares

Leave a Reply

Previous Post
Encrypting and Decrypting information with cryptography

Encrypting and Decrypting information with cryptography

Next Post
Generating keys securely with the secrets and hashlib modules

Generating keys securely with the secrets and hashlib modules

Related Posts