Python AES 加密解密后文本为空问题的解决方案

16次阅读

Python AES 加密解密后文本为空问题的解决方案

本文旨在解决在使用 Python 的 Crypto 库进行 AES 加密解密时,解密后得到空字符串的问题。通过分析代码,找出问题根源在于密钥处理方式不正确,并提供修正后的代码示例,确保加密和解密过程的正确性,最终实现数据的可靠保护。

在使用 Python 的 Crypto 库进行 AES 加密和解密时,有时可能会遇到解密后文本为空的情况。这通常是由于密钥处理不当造成的。以下将详细介绍如何避免这个问题,并提供正确的代码示例。

问题在于,原始代码中,当提供密钥给 AESCipher 构造函数时,错误地计算了密钥的哈希值,而正确的做法应该是对密钥进行 Base64 解码。AESCipher.get_key 方法将密钥编码为 Base64 字符串,因此在解密时需要进行逆向操作。

正确的 AESCipher 构造函数应如下所示:

立即学习Python免费学习笔记(深入)”;

import hashlib from Crypto.Cipher import AES from Crypto import Random from base64 import b64encode, b64decode   class AESCipher(object):     def __init__(self, key=None):         # Initialize the AESCipher object with a key,          # defaulting to a randomly generated key         self.block_size = AES.block_size         if key:             self.key = b64decode(key.encode())         else:             self.key = Random.new().read(self.block_size)      def encrypt(self, plain_text):         # Encrypt the provided plaintext using AES in CBC mode         plain_text = self.__pad(plain_text)         iv = Random.new().read(self.block_size)         cipher = AES.new(self.key, AES.MODE_CBC, iv)         encrypted_text = cipher.encrypt(plain_text)         # Combine IV and encrypted text, then base64 encode for safe representation         return b64encode(iv + encrypted_text).decode("utf-8")      def decrypt(self, encrypted_text):         # Decrypt the provided ciphertext using AES in CBC mode         encrypted_text = b64decode(encrypted_text)         iv = encrypted_text[:self.block_size]         cipher = AES.new(self.key, AES.MODE_CBC, iv)         plain_text = cipher.decrypt(encrypted_text[self.block_size:])         return self.__unpad(plain_text)      def get_key(self):         # Get the base64 encoded representation of the key         return b64encode(self.key).decode("utf-8")      def __pad(self, plain_text):         # Add PKCS7 padding to the plaintext         number_of_bytes_to_pad = self.block_size - len(plain_text) % self.block_size         padding_bytes = bytes([number_of_bytes_to_pad] * number_of_bytes_to_pad)         padded_plain_text = plain_text.encode() + padding_bytes         return padded_plain_text      @staticmethod     def __unpad(plain_text):         # Remove PKCS7 padding from the plaintext         last_byte = plain_text[-1]         return plain_text[:-last_byte] if isinstance(last_byte, int) else plain_text

关键的修改在于 __init__ 方法中,当 key 参数存在时,使用 b64decode(key.encode()) 对其进行 Base64 解码,而不是计算哈希值。

完整代码示例:

Python AES 加密解密后文本为空问题的解决方案

小文AI论文

轻松解决论文写作难题,AI论文助您一键完成,仅需一杯咖啡时间,即可轻松问鼎学术高峰!

Python AES 加密解密后文本为空问题的解决方案69

查看详情 Python AES 加密解密后文本为空问题的解决方案

以下是包含修正后的 AESCipher 类的完整代码示例,并包含加密、解密以及保存到文件等功能。

import hashlib from Crypto.Cipher import AES from Crypto import Random from base64 import b64encode, b64decode   class AESCipher(object):     def __init__(self, key=None):         # Initialize the AESCipher object with a key, defaulting to a randomly generated key         self.block_size = AES.block_size         if key:             self.key = b64decode(key.encode())         else:             self.key = Random.new().read(self.block_size)      def encrypt(self, plain_text):         # Encrypt the provided plaintext using AES in CBC mode         plain_text = self.__pad(plain_text)         iv = Random.new().read(self.block_size)         cipher = AES.new(self.key, AES.MODE_CBC, iv)         encrypted_text = cipher.encrypt(plain_text)         # Combine IV and encrypted text, then base64 encode for safe representation         return b64encode(iv + encrypted_text).decode("utf-8")      def decrypt(self, encrypted_text):         # Decrypt the provided ciphertext using AES in CBC mode         encrypted_text = b64decode(encrypted_text)         iv = encrypted_text[:self.block_size]         cipher = AES.new(self.key, AES.MODE_CBC, iv)         plain_text = cipher.decrypt(encrypted_text[self.block_size:])         return self.__unpad(plain_text)      def get_key(self):         # Get the base64 encoded representation of the key         return b64encode(self.key).decode("utf-8")      def __pad(self, plain_text):         # Add PKCS7 padding to the plaintext         number_of_bytes_to_pad = self.block_size - len(plain_text) % self.block_size         padding_bytes = bytes([number_of_bytes_to_pad] * number_of_bytes_to_pad)         padded_plain_text = plain_text.encode() + padding_bytes         return padded_plain_text      @staticmethod     def __unpad(plain_text):         # Remove PKCS7 padding from the plaintext         last_byte = plain_text[-1]         return plain_text[:-last_byte] if isinstance(last_byte, int) else plain_text   def save_to_notepad(text, key, filename):     # Save encrypted text and key to a file     with open(filename, 'w') as file:         file.write(f"Key: {key}nEncrypted text: {text}")     print(f"Text and key saved to {filename}")  def encrypt_and_save():     # Take user input, encrypt, and save to a file     user_input = ""     while not user_input:         user_input = input("Enter the plaintext: ")      aes_cipher = AESCipher()  # Randomly generated key      encrypted_text = aes_cipher.encrypt(user_input)     key = aes_cipher.get_key()      filename = input("Enter the filename (including .txt extension): ")     save_to_notepad(encrypted_text, key, filename)   def decrypt_from_file():     # Decrypt encrypted text from a file using a key     filename = input("Enter the filename to decrypt (including .txt extension): ")     with open(filename, 'r') as file:         lines = file.readlines()         key = lines[0].split(":")[1].strip()         encrypted_text = lines[1].split(":")[1].strip()      aes_cipher = AESCipher(key)     decrypted_bytes = aes_cipher.decrypt(encrypted_text)      # Decoding only if the decrypted bytes are not empty     decrypted_text = decrypted_bytes.decode("utf-8") if decrypted_bytes else ""     print("Decrypted Text:", decrypted_text)   def encrypt_and_decrypt_in_command_line():     # Encrypt and then decrypt user input in the command line     user_input = ""     while not user_input:         user_input = input("Enter the plaintext: ")      aes_cipher = AESCipher()      encrypted_text = aes_cipher.encrypt(user_input)     key = aes_cipher.get_key()      print("Key:", key)     print("Encrypted Text:", encrypted_text)      decrypted_bytes = aes_cipher.decrypt(encrypted_text)     decrypted_text = decrypted_bytes.decode("utf-8") if decrypted_bytes else ""     print("Decrypted Text:", decrypted_text)   # Menu Interface while True:     print("nMenu:")     print("1. Encrypt and save to file")     print("2. Decrypt from file")     print("3. Encrypt and decrypt in command line")     print("4. Exit")      choice = input("Enter your choice (1, 2, 3, or 4): ")      if choice == '1':         encrypt_and_save()     elif choice == '2':         decrypt_from_file()     elif choice == '3':         encrypt_and_decrypt_in_command_line()     elif choice == '4':         print("Exiting the program. goodbye!")         break     else:         print("Invalid choice. Please enter 1, 2, 3, or 4.")

注意事项:

  • 密钥安全: 请务必安全地存储和传输密钥。避免将密钥硬编码到代码中。
  • 编码问题: 在处理文本时,确保使用一致的编码方式(如 UTF-8)。
  • Padding: PKCS7 padding 是 AES 加密常用的填充方式,确保加密和解密都使用相同的填充方式。
  • IV (Initialization Vector): 每次加密都应该使用不同的 IV,以增强安全性。

总结:

通过修正 AESCipher 类的构造函数,确保在解密时正确处理密钥,可以有效解决 AES 解密后文本为空的问题。同时,注意密钥安全、编码一致性以及正确的填充方式,可以提高加密系统的安全性。

python go 编码 ai notepad crypto Python 构造函数 字符串 padding

text=ZqhQzanResources