使用 PyCrypto AES 进行 Python 加密

标签 python pycrypto

我今天刚找到 pycrypto,我一直在研究我的 AES 加密类(class)。不幸的是,它只成功了一半。 self.h.md5 以十六进制格式输出 md5 哈希,并且是 32byte。 这是输出。它似乎解密了消息,但它在解密后放置了随机字符,在这种情况下\n\n\n...我想我的 self.data block 大小有问题,有人知道如何解决这个问题吗?

Jans-MacBook-Pro:test2 jan$ ../../bin/python3 data.py b'RLfGmn5jf5WTJphnmW0hXG7IaIYcCRpjaTTqwXR6yiJCUytnDib+GQYlFORm+jIctest 1 2 3 4 5 endtest\n\n\n\n\n\n\n\n\n\n'

from Crypto.Cipher import AES
from base64 import b64encode, b64decode
from os import urandom

class Encryption():
    def __init__(self):
        self.h = Hash()

    def values(self, data, key):
        self.data = data
        self.key = key
        self.mode = AES.MODE_CBC
        self.iv = urandom(16)
        if not self.key:
            self.key = Cfg_Encrypt_Key
        self.key = self.h.md5(self.key, True)

    def encrypt(self, data, key):
        self.values(data, key)
        return b64encode(self.iv + AES.new(self.key, self.mode, self.iv).encrypt(self.data))

    def decrypt(self, data, key):
        self.values(data, key)
        self.iv = b64decode(self.data)[:16]
        return AES.new(self.key, self.mode, self.iv).decrypt(b64decode(self.data)[16:])

最佳答案

老实说,字符 "\n\n\n\n\n\n\n\n\n\n" 在我看来并不那么随意。 ;-)

您正在 CBC 模式下使用 AES。这要求明文和密文的长度始终是 16 字节的倍数。使用您显示的代码,您实际上应该看到当 data 传递给 encrypt() 不满足此类条件时引发的异常。看起来您添加了足够多的换行符 ('\n' 到任何输入,直到明文恰好对齐。

除此之外,还有两种常见的方法可以解决对齐问题:

  1. 从 CBC (AES.MODE_CBC) 切换到 CFB (AES.MODE_CFB)。使用 PyCrypto 默认使用的 segment_size,您将不会对明文和密文长度有任何限制。

  2. 保留 CBC 并使用类似 PKCS#7 的填充方案,即:

    • 在加密 X 字节的明文之前,在后面追加到达下一个 16 字节边界所需的字节数。所有填充字节都具有相同的值:您要添加的字节数:

      length = 16 - (len(data) % 16)
      data += bytes([length])*length
      

      那是 Python 3 风格。在 Python 2 中,您将拥有:

      length = 16 - (len(data) % 16)
      data += chr(length)*length
      
    • 解密后,从明文后面删除填充指示的字节数:

      data = data[:-data[-1]]
      

尽管我理解您的情况只是类练习,但我想指出,在没有任何形式的身份验证(例如 MAC)的情况下发送数据是不安全的。

关于使用 PyCrypto AES 进行 Python 加密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14179784/

相关文章:

python - 如何使用 PropertyMock 在 pytest 单元测试中返回请求响应属性?

python - QtWebkit:loadFinished 和 loadProgress 槽永远不会执行

python - 如何验证由 openssl 创建的 pycrypto 签名?

python - 使用 pyCrypto 的 RSA python 公钥

python - 使用 Python dataframe 高效地将数百万行写入文件

python - 如何在python中的每个字节后添加空格

Python - 用于从 CSV 文件中的整行中删除引号的正则表达式

php - 在 PHP 中加密文本并在 Python 中解密

python - 即使只有一个字符数据,PyCrypto Cyphertext 的长度也不正确

python - pycrypto 适用于 python2.7 而不是 python3.6