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
#!/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:
-
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.
- This function takes a pixel value (
-
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’).
- This function takes a pixel value (
-
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.
-
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.
-
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.
-
Main Code:
- The script tests the
hide_messagefunction by hiding the message “Hidden message” in the ‘python.png’ image and saving the result as ‘python_secrets.png’. - It then tests the
extract_messagefunction by attempting to extract the hidden message from ‘python_secrets.png’.
- The script tests the
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:
-
Installation: Ensure you have Python and Stegano installed:
pip install stegano -
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
- Revealing the Message:
# Extract hidden message from "secret_photo.jpg" using password "mypassword"
stegano -d -p mypassword secret_photo.jpg
- 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
- 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.
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)# 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)-
_validate_imagefunction:- Validates that the image has a supported pixel format (
RGB,RGBA, orCMYK). - Raises an exception if the image format is
JPEG(incompatible with steganography).
- Validates that the image has a supported pixel format (
-
encode_imdatafunction:- 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.
- Takes a sequence of pixels (
-
encode_inplacefunction:- Takes an image and the data to be encoded.
- Calls
_validate_imageto ensure the image is in a supported format. - Iterates over the image pixels, calling
encode_imdatato modify the pixel values in place.
-
encodefunction:- Takes an image and the data to be encoded.
- Creates a copy of the image and calls
encode_inplaceon the copy. - Saves the resulting image with the hidden message as ‘python-secret.png’.
- Returns the modified image.
-
decode_imdatafunction:- 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.
- Takes a sequence of pixels (
-
decodefunction:- Takes an image and decodes the hidden message using
decode_imdata.
- Takes an image and decodes the hidden message using
-
Main Code:
- Opens the image ‘python.png’.
- Calls
encodeto hide the message ‘this is a secret message’ in the image. - Opens the encoded image ‘python-secret.png’.
- Calls
decodeto extract and print the hidden message.