Python cryptography加密图片后Rust解密Base64错误的解决办法
AES-CBC 加密解密问题解决方案
方案一:修改 Rust 代码直接解密原始加密字节
这是最直接的解决方式,无需改动 Python 端代码。错误根源是你在 Rust 中多余执行了 Base64 解码步骤——加密后的原始字节是任意二进制数据,并非合法的 Base64 编码字符串,直接解码必然触发非法字节错误。
Rust 示例代码(依赖 aes 和 cbc crate)
先在 Cargo.toml 中添加依赖:
[dependencies] aes = "0.8" cbc = "0.1" hex = "0.4" # 若密钥/IV以十六进制存储则需,可按需调整
解密逻辑示例:
use aes::Aes256; use cbc::cipher::{BlockDecryptMut, KeyIvInit}; use std::fs; type Aes256CbcDecryptor = cbc::Decryptor<Aes256>; fn main() { // 读取加密后的原始二进制文件 let encrypted_data = fs::read("encrypted_image.bin").expect("读取加密文件失败"); // 替换为你实际使用的密钥和IV(必须与Python加密时一致) let key = hex::decode("你的256位密钥十六进制字符串").expect("密钥格式错误"); let iv = hex::decode("你的128位IV十六进制字符串").expect("IV格式错误"); // 初始化解密器 let mut decryptor = Aes256CbcDecryptor::new(&key.into(), &iv.into()); // 执行解密(CBC模式要求数据长度为块大小的倍数,加密时已处理填充) let mut decrypted_data = encrypted_data.clone(); decryptor.decrypt_blocks_mut(&mut decrypted_data); // 移除PKCS#7填充(cryptography库默认使用该填充方式) let padding_len = decrypted_data.last().unwrap().clone() as usize; decrypted_data.truncate(decrypted_data.len() - padding_len); // 保存解密后的图片 fs::write("decrypted_image.jpg", decrypted_data).expect("写入解密文件失败"); }
方案二:修改 Python 代码添加 Base64 编码
如果你的场景需要加密后的数据为可打印字符串(比如在文本协议中传输),可以修改 Python 代码将加密字节转成 Base64 编码后保存,这样 Rust 端的 Base64 解码步骤就合理了。
Python 示例代码修改(新增 Base64 编码)
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend import base64 import os def encrypt_image(input_path, output_path, key): backend = default_backend() # 生成IV(需保存给解密环节使用) iv = os.urandom(16) cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) encryptor = cipher.encryptor() with open(input_path, 'rb') as f: plaintext = f.read() # PKCS#7填充(与cryptography默认行为一致) padding_len = 16 - (len(plaintext) % 16) plaintext += bytes([padding_len]) * padding_len ciphertext = encryptor.update(plaintext) + encryptor.finalize() # 将IV与密文合并后转Base64,写入文件 encrypted_b64 = base64.b64encode(iv + ciphertext).decode('utf-8') with open(output_path, 'w') as f: f.write(encrypted_b64) # 使用示例(密钥需为16/24/32字节,对应AES-128/192/256) key = b'你的32字节密钥' encrypt_image('original.jpg', 'encrypted_b64.txt', key)
此时 Rust 端可先执行 Base64 解码,拆分出 IV 和密文后再解密,即可避免之前的错误。
内容的提问来源于stack exchange,提问作者Youdi
相关产品推荐
相关产品推荐

