AES加密文件后附加到图片后面传输

加密过程为:1、将文档压缩成zip;2、将zip字节流用aes加密;3、将加密后的字节流附加到图片后面。
解密流程为:1、从图片后面取出加密后的字节流;2、使用aes解密出zip数据;3、解压zip。

import zipfile
from pathlib import Path
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad

# The following variables modified or not is optional.
aes_key = 'justwrapaplaintobase64'
separator = b'donotdonotdonotdothis'
hiden_data_zip_filename = 'h.zip'  # 目标文件压缩后的zip
hiden_data_extract_zip_filename = 'eh.zip'  # 从img提取出的zip
# Someone who using this program should moidfy the following variables.
hiden_filename = 'ok.xlsx'  # 目标文件
original_img_filename = 'aa.png'  # 原img
encrypted_img_filename = 'wx.png'  # 拼合后的img

def append_data_to_image(image_path: str, append_data: bytes):
    image_data = Path(image_path).read_bytes()
    with Path(encrypted_img_filename).open('wb') as new_img_file:
        new_img_file.write(image_data)
        new_img_file.write(separator)
        new_img_file.write(append_data)

def extract_data_from_image(image_path: str):
    img_data = Path(image_path).read_bytes()
    if img_data.find(separator) == -1:
        raise Exception("Target data not found.")
    return img_data[img_data.find(separator) + len(separator):]

def zip_file(file_path: str, zip_path: str) -> bytes:
    with zipfile.ZipFile(zip_path, 'w') as zipf:
        zipf.write(file_path)
    return Path(zip_path).read_bytes()

def unzip_file():
    with zipfile.ZipFile(hiden_data_zip_filename, 'r') as zip_ref:
        zip_ref.extractall(str(Path(__file__).parent))

def aes_encrypt(data_bytes: bytes, key: bytes) -> bytes:
    cipher = AES.new(key, AES.MODE_CBC)
    iv = cipher.iv
    padded_data = pad(data_bytes, AES.block_size)
    ciphertext = cipher.encrypt(padded_data)
    return iv + ciphertext

def aes_decrypt(encrypted_data: bytes, key: bytes) -> bytes:
    iv = encrypted_data[:AES.block_size]
    ciphertext = encrypted_data[AES.block_size:]
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_plaintext = cipher.decrypt(ciphertext)
    plaintext = unpad(padded_plaintext, AES.block_size)
    return plaintext

def init_aes_key(key: str) -> bytes:
    if len(key) == 0:
        raise Exception("At least one char of key was needed.")
    return ((key * 16)[:16]).encode('utf8')

def append_data_demo():
    zip_data = zip_file(hiden_filename, hiden_data_zip_filename)
    encrypted_zip_data = aes_encrypt(zip_data, init_aes_key(aes_key))
    append_data_to_image(original_img_filename, encrypted_zip_data)

def extract_data_demo():
    extract_data = extract_data_from_image(encrypted_img_filename)
    original_data = aes_decrypt(extract_data, init_aes_key(aes_key))
    Path(hiden_data_extract_zip_filename).write_bytes(original_data)
    unzip_file()

if __name__ == "__main__":
    append_data_demo()
    extract_data_demo()
posted @ 2024-12-11 23:30  那个白熊  阅读(15)  评论(0编辑  收藏  举报