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
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值