AES 密钥长度不正确89 字节

问题描述

有人可以指导我们在这里可能做错了什么吗? 代码"raise ValueError("Incorrect AES key length (%d bytes)" % len(key)) 而崩溃 ValueError: AES 密钥长度不正确(89 字节)"

注意:文件 symmetric_key.txt 包含与硬编码变量完全相同的序列 即 [EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\ x9e

#!/usr/bin/python3

from Crypto import Random

from Crypto.Cipher import AES 

import os

import os.path

from os import listdir

from os.path import isfile,join

import time

import sys

class Encryptor:
    def __init__(self,key):
        self.key = key

    def pad(self,s):
        return s + b"\0" * (AES.block_size - len(s) % AES.block_size)

    def encrypt(self,message,key,key_size=256):
        message = self.pad(message)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(key,AES.MODE_CBC,iv)
        return iv + cipher.encrypt(message)

    def encrypt_file(self,file_name):
        with open(file_name,'rb') as fo:
            plaintext = fo.read()
        enc = self.encrypt(plaintext,self.key)
        with open(file_name + ".enc",'wb') as fo:
            fo.write(enc)
        os.remove(file_name)

    def decrypt(self,ciphertext,key):
        iv = ciphertext[:AES.block_size]
        cipher = AES.new(key,iv)
        plaintext = cipher.decrypt(ciphertext[AES.block_size:])
        return plaintext.rstrip(b"\0")

    def decrypt_file(self,'rb') as fo:
            ciphertext = fo.read()
        dec = self.decrypt(ciphertext,self.key)
        with open(file_name[:-4],'wb') as fo:
            fo.write(dec)
        os.remove(file_name)

    def getAllFiles(self):
        dir_path = os.path.dirname(os.path.realpath(__file__))
        dirs = []
        for dirName,subdirList,fileList in os.walk(dir_path):
            for fname in fileList:
                if (fname != 'encryptor_git.py' and fname != 'data.txt.enc'):
                    dirs.append(dirName + "\\" + fname)
        return dirs

    def encrypt_all_files(self):
        dirs = self.getAllFiles()
        for file_name in dirs:
            self.encrypt_file(file_name)

    def decrypt_all_files(self):
        dirs = self.getAllFiles()
        for file_name in dirs:
            self.decrypt_file(file_name)

## file fetching the symmetric key
with open("symmetric_key.txt","rb") as k1:
    key_from_file = k1.read()
    
## this hardcoded key works fine
key = b'[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e'
key = key_from_file

print (type (key))


enc = Encryptor(key) ## created object of Encryptor class 
clear = lambda: os.system('cls') 


enc.encrypt_file(str(input("Enter name of file to encrypt: ")))            

解决方法

键的代码版本是通过字符串文字定义的。当 Python 解释该行时:

key = b'[EX\xc8\xd5\xbfI{\xa2$\x05(\xd5\x18\xbf\xc0\x85)\x10nc\x94\x02)j\xdf\xcb\xc4\x94\x9d(\x9e'

它处理所有 \xc8 类型的序列并将它们转换为适当的内部表示。另一方面,从文件中读取的相同字符串保持原样。我宁愿以十六进制或 base64 编码存储密钥,但如果您必须处理您拥有的内容,则可以使用例如ast.literal_eval

key = ast.literal_eval(f'"{key_from_file}"')

更新:如果 key_from_filebytes,而不是字符串,就像在您的示例中一样,引号是多余的,例如

key = ast.literal_eval(str(key_from_file))

话虽如此,更可靠的方法是使用 base64 来存储密钥。