Python实现LSB算法图片隐写、解密、判断图片是否经过LSB隐写

  • 此处原图片和代码在同一文件夹下,文件名为"circle.png"。

  • 此处写入信息为"明天老地方见"。

  • 此处隐写后的新图片为"new_img.png"

  • 此处使用的秘钥为'She loves to read books at night'的base64编码。

  • 使用Fernet 密钥进行加密,请注意,Fernet密钥需要是 32 字节的base64 编码字符串。

Fernet 密钥会经过这样的转换:key = base64.urlsafe_b64decode(key)

也就是说,有着这样的转换过程:

She loves to read books at night(长度必须为32

↓ base64编码

U2hlIGxvdmVzIHRvIHJlYWQgYm9va3MgYXQgbmlnaDE=(长度为44)

↓ Fernet 密钥的转换 key = base64.urlsafe_b64decode(key)

b'She loves to read books at nigh1'(长度为32)

  • 提供几段长度为32的英文:

  1. This cake is delicious and sweet

  1. She loves to play the piano well

  1. You are a very good friend to me

  1. hello world!!!!!!!!!!!!!!!!!!!!!

  • 对秘钥错误的情况也进行了处理,可以用上面的长度为32的英文试一下秘钥错误的情况

import base64
import cryptography
from cryptography.fernet import Fernet
from cryptography.fernet import InvalidToken
from stegano import lsb


def encrypt_message(message, key):
    """
    用以加密信息
    :param message: 要加密的明文
    :param key: 密码。应为32字节的base64编码字符串
    :return: 返回加密后的密文
    """
    f = Fernet(key)
    return f.encrypt(message.encode()).decode()


def decrypt_message(encrypted_message, key):
    """
    用以解密信息
    :param encrypted_message: 要解密的密文
    :param key: 密码。应为32字节的base64编码字符串
    :return: 返回解密后的明文
    """
    f = Fernet(key)
    return f.decrypt(encrypted_message.encode()).decode()


def hide_message(original_image, message, key):
    """
    用以向图片写入信息
    :param original_image:原始图像文件的路径
    :param message: 想要写入的明文。字符串
    :param key: 密码。应为32字节的base64编码字符串
    :return:返回一个新的图像文件
    """
    if len(str(key)) != 44:  # 注意int不可以用len(),所以要转换为str
        print("密码格式错误!")
        return None
    encrypted_message = encrypt_message(message, key)  # 加密
    return lsb.hide(original_image, encrypted_message)


def extract_message(stegano_image, key):
    """
    用以解密图像中提取隐藏的信息
    :param stegano_image:需要解密的经过隐写的图片
    :param key:密码。应为32字节的base64编码字符串
    :return:返回解密后的信息
    """
    try:
        if len(str(key)) != 44:  # 注意int不可以用len(),所以要转换为str
            print("密码格式错误!")
            return None
        encrypted_message = lsb.reveal(stegano_image)
        message = decrypt_message(encrypted_message, key)
        return message
    except cryptography.fernet.InvalidSignature:
        # Signature did not match digest
        print("密码错误!")
        return None
    except InvalidToken:
        print("密码错误!")
        return None


def lsb_detection(image_path):
    """
    用以检测图片是否经过LSB隐写。
    当图片没有经过LSB隐写时,程序会报错IndexError: Impossible to detect message.
    所以要捕获该异常
    """
    try:
        message = lsb.reveal(image_path)  # 提取隐藏的信息
        # 如果提取出来的信息不是None或空字符串,那么就返回1;否则就返回0
        if message:
            print("该图片可能经过LSB隐写")
            return 1  # 可能经过了LSB隐写
        else:
            return 0  # 可能没有经过LSB隐写

    except IndexError:  # 捕获IndexError异常
        print("该图片没有经过LSB隐写")
        return 0


my_image = 'circle.png'
text = 'She loves to read books at night'  # 长度为32
my_key = base64.b64encode(text.encode('utf-8')).decode('utf-8')  # 转换为base64编码,转换后长度为44
# Fernet密钥需要是 32 字节的base64 编码字符串。
my_message = '明天老地方见'
my_key_bytes = base64.urlsafe_b64decode(my_key)

# 隐藏信息
new_image = hide_message(my_image, my_message, my_key)
new_image.save('new_img.png')

# 提取信息
extracted_message = extract_message('new_img.png', my_key)
print(extracted_message)

# 检测是否经过LSB隐写
lsb_detection('circle.png')

输出结果:

明天老地方见
该图片没有经过LSB隐写
  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: 在Python实现LSB隐写技术,可以通过以下步骤: 1. 加载图像文件 使用Python的Pillow库(PIL)加载图像文件。可以使用以下代码: ``` from PIL import Image # 加载图像文件 img = Image.open('input_image.png') ``` 2. 将文本转换为二进制字符串 将要隐藏的文本转换为二进制字符串。可以使用以下代码: ``` message = 'hello world' binary_message = ''.join(format(ord(c), '08b') for c in message) ``` 这将把文本"hello world"转换为二进制字符串"01101000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100"。 3. 将二进制字符串嵌入图像像素中 将二进制字符串嵌入到图像像素中。可以使用以下代码: ``` # 获取图像的像素 pixels = list(img.getdata()) # 将二进制字符串嵌入到像素中 binary_index = 0 for i in range(len(pixels)): r, g, b = pixels[i] if binary_index < len(binary_message): pixels[i] = (r, g, int(bin(b)[2:9] + binary_message[binary_index], 2)) binary_index += 1 else: break # 创建新图像 new_img = Image.new(img.mode, img.size) new_img.putdata(pixels) ``` 这将遍历图像的每个像素,并将二进制字符串的每个位嵌入到蓝色通道的最后一位中。 4. 保存新图像 最后,将新图像保存到文件中。可以使用以下代码: ``` new_img.save('output_image.png') ``` 这将保存包含隐藏文本的新图像。 完整的代码如下: ``` from PIL import Image # 加载图像文件 img = Image.open('input_image.png') # 将文本转换为二进制字符串 message = 'hello world' binary_message = ''.join(format(ord(c), '08b') for c in message) # 获取图像的像素 pixels = list(img.getdata()) # 将二进制字符串嵌入到像素中 binary_index = 0 for i in range(len(pixels)): r, g, b = pixels[i] if binary_index < len(binary_message): pixels[i] = (r, g, int(bin(b)[2:9] + binary_message[binary_index], 2)) binary_index += 1 else: break # 创建新图像 new_img = Image.new(img.mode, img.size) new_img.putdata(pixels) # 保存新图像 new_img.save('output_image.png') ``` ### 回答2: LSB(最低有效位)隐写技术是一种常见的图像隐写技术,通过将秘密信息的比特位嵌入到载体图像的像素的最低位中,来隐藏秘密信息。 Python可以通过使用PIL(Python Imaging Library)库来实现LSB隐写技术。下面是一个简单的示例代码: ``` from PIL import Image import binascii def lsb_hide(secret, carrier): # 将秘密信息转换为二进制 binary_secret = bin(int(binascii.hexlify(secret.encode('utf-8')), 16))[2:] # 打开载体图像 image = Image.open(carrier) pixels = image.load() # 获取图像的宽度和高度 width, height = image.size # 获取秘密信息的长度 secret_length = len(binary_secret) # 检查秘密信息是否太长以适应载体图像 if secret_length > width * height: raise ValueError("秘密信息太长无法嵌入到载体图像中") # 嵌入秘密信息 index = 0 for y in range(height): for x in range(width): # 获取像素的RGB值 r, g, b = pixels[x, y] # 将秘密信息的比特位嵌入到RGB的最低位中 if index < secret_length: r &= 0b11111110 r |= int(binary_secret[index]) index += 1 # 更新图像的RGB值 pixels[x, y] = (r, g, b) # 保存修改后的载体图像 image.save('stego_image.png') def lsb_reveal(stego_image): # 打开隐写图像 image = Image.open(stego_image) pixels = image.load() # 获取图像的宽度和高度 width, height = image.size # 提取秘密信息 binary_secret = "" for y in range(height): for x in range(width): # 获取像素的RGB值 r, _, _ = pixels[x, y] # 提取RGB的最低位 binary_secret += str(r & 1) # 将二进制转换为字符串 secret = binascii.unhexlify('%x' % (int(binary_secret, 2))) return secret.decode('utf-8') # 示例用法 secret_message = "这是一个秘密信息" carrier_image = "carrier.png" # 嵌入秘密信息 lsb_hide(secret_message, carrier_image) # 提取秘密信息 retrieved_secret = lsb_reveal("stego_image.png") print("提取的秘密信息:", retrieved_secret) ``` 上述代码中,`lsb_hide`函数用于将秘密信息嵌入到载体图像中,而`lsb_reveal`函数用于从隐写图像中提取秘密信息。通过这种方式,我们可以将秘密信息嵌入到载体图像中,而不会对图像的外观产生明显的变化。 ### 回答3: LSB隐写技术是一种基于最低有效位的隐写技术,可以将秘密信息隐藏在图像、音频或视频等多媒体文件中。下面是一个使用Python实现LSB隐写技术的简单示例: 步骤1:读取原始图像和待隐藏的秘密信息。 ```python from PIL import Image # 读取原始图像 image = Image.open("original_image.jpg") pixels = list(image.getdata()) width, height = image.size # 读取待隐藏的秘密信息 secret_message = "This is a secret message." ``` 步骤2:将秘密信息转换为二进制字符串。 ```python message_binary = ''.join(format(ord(char), '08b') for char in secret_message) ``` 步骤3:将秘密信息隐藏在图像的像素中。 ```python index = 0 for i in range(len(pixels)): r, g, b = pixels[i] # 隐藏秘密信息 if index < len(message_binary): r = (r & 0xFE) | int(message_binary[index]) index += 1 pixels[i] = (r, g, b) # 创建新的图像并保存 new_image = Image.new(image.mode, image.size) new_image.putdata(pixels) new_image.save("stego_image.jpg") ``` 步骤4:解密隐藏的秘密信息。 ```python stego_image = Image.open("stego_image.jpg") stego_pixels = list(stego_image.getdata()) # 从像素中提取秘密信息 extracted_message = '' for i in range(len(stego_pixels)): r, g, b = stego_pixels[i] extracted_bit = str(r & 1) extracted_message += extracted_bit # 当提取到终止字符时停止 if len(extracted_message) % 8 == 0 and extracted_message[-8:] == '00000000': break # 将二进制字符串转换为可读文本 message = ''.join(chr(int(extracted_message[i:i + 8], 2)) for i in range(0, len(extracted_message), 8)) ``` 以上是一个简单的Python实现LSB隐写技术的示例。需要注意的是,在实际应用中,需要考虑到图像的大小和通道数等因素,以及使用更复杂的算法来增加隐写的安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值