基于AES算法的图片加解密报错:密钥长度不正确(64字节)
问题解决:AES密钥长度错误(64字节)
问题原因
AES算法仅支持**16字节(128位)、24字节(192位)、32字节(256位)**的密钥长度。你的代码中通过hashlib.sha256(...).hexdigest()生成的是64个字符的字符串(64字节),不符合AES的密钥要求,因此触发错误。
修复方案
1. 修正密钥生成逻辑
将哈希结果从十六进制字符串(hexdigest)改为原始字节串(digest),sha256的原始哈希值正好是32字节,符合AES-256的密钥长度要求。
修改image_open和cipher_open函数中的密钥生成代码:
# 原代码 password = hashlib.sha256(enc_pass.encode('utf-8')).hexdigest() # 修改后 password = hashlib.sha256(enc_pass.encode('utf-8')).digest()
2. 修复解密函数的语法错误
解密函数中有一行代码缺少右括号,导致运行报错:
# 原代码 decrypted = decrypted.replace("n","" # 修改后 decrypted = decrypted.replace("n", "")
3. 可选优化:使用随机IV(增强安全性)
当前代码使用固定IV'This is an IV456',虽然能运行,但固定IV会降低加密安全性。建议生成随机IV并随密文一起存储,示例如下:
# 加密时生成随机IV iv = os.urandom(16) obj = AES.new(password, AES.MODE_CBC, iv) # 将IV写入密文文件开头 g = open(cipher_name, 'wb') g.write(iv) g.write(ciphertext) # 解密时读取IV cipher = open(ciphername, 'rb') iv = cipher.read(16) ciphertext = cipher.read() obj2 = AES.new(password, AES.MODE_CBC, iv)
完整修改后的关键代码片段
加密按钮事件
def image_open(): global file_path_e enc_pass = passg.get() if enc_pass == "": pass_alert() else: # 改用digest获取32字节原始哈希 password = hashlib.sha256(enc_pass.encode('utf-8')).digest() filename = filedialog.askopenfilename() file_path_e = os.path.dirname(filename) encrypt(filename,password)
解密按钮事件
def cipher_open(): global file_path_d dec_pass = passg.get() if dec_pass == "": pass_alert() else: # 改用digest获取32字节原始哈希 password = hashlib.sha256(dec_pass.encode('utf-8')).digest() filename = filedialog.askopenfilename() file_path_d = os.path.dirname(filename) decrypt(filename,password)
修复后的解密函数
def decrypt(ciphername,password): secret_image = Image.open("secret.jpeg") ima = Image.open("2-share_encrypt.jpeg") new_image = generate_image_back(secret_image, ima) new_image.save("2-share_decrypt.jpeg") print("2-share Decryption done....") # 用二进制模式读取密文,避免编码问题 cipher = open(ciphername,'rb') ciphertext = cipher.read() # 解密密文 obj2 = AES.new(password, AES.MODE_CBC, b'This is an IV456') decrypted = obj2.decrypt(ciphertext).decode('utf-8') # 修复语法错误:添加右括号 decrypted = decrypted.replace("n", "") # 提取图像尺寸 newwidth = decrypted.split("w")[1] newheight = decrypted.split("h")[1] # 移除尺寸标记 heightr = "h" + str(newheight) + "h" widthr = "w" + str(newwidth) + "w" decrypted = decrypted.replace(heightr,"") decrypted = decrypted.replace(widthr,"") # 重建像素数组 step = 3 finaltextone=[decrypted[i:i+step] for i in range(0, len(decrypted), step)] finaltexttwo=[(int(finaltextone[int(i)])-100,int(finaltextone[int(i+1)])-100,int(finaltextone[int(i+2)])-100) for i in range(0, len(finaltextone), step)] # 生成解密后的图像 newim = Image.new("RGB", (int(newwidth), int(newheight))) newim.putdata(finaltexttwo) newim.save("visual_decrypt.jpeg") print("Visual Decryption done......")
注意:读取和写入密文时建议使用二进制模式(
'rb'/'wb'),避免字符编码问题导致密文损坏。
内容的提问来源于stack exchange,提问作者Saadi Qazi
相关产品推荐
相关产品推荐

