在python中使用CBC模式进行AES加密128位密钥

问题描述

我使用以下代码在AES中加密了文本,并使用在线解密网站(Website 1Website 2)对密文进行了解密。 但是,所有网站的解密文本前面都包含一些不需要的字符串,如this图片所示。

import base64
import hashlib
from Crypto import Random
from Crypto.Cipher import AES

key = b'asdfghjklqwertyu'

class AESCipher(object):

    def __init__(self,key): 
        self.bs = AES.block_size
        self.key = key

    def encrypt(self,raw):
        raw = self._pad(raw)
        iv = Random.new().read(AES.block_size)
        cipher = AES.new(self.key,AES.MODE_CBC,iv)
        return base64.b64encode(iv + cipher.encrypt(raw.encode()))

    def _pad(self,s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)

a = AESCipher(key)
print(a.encrypt('hey There!'))

解决方法

devlan网站解释了

强烈建议使用

CBC模式,它需要IV才能使每条消息唯一。 如果未输入任何IV,则将在此处将CBC模式使用默认值,并且默认为基于零的字节[16]

因此,您的前置IV被视为密文块。现在,您在那里有两个街区。在CBC模式下,解密的执行方式为(块从1开始计数);

Pi = Dec(key,Ci) + Ci
C0 = IV
  • 您的P1 = Dec(key,C1) + C0,由于IV = 0
  • ,这是垃圾
  • 您的P2 = Dec(key,C2) + C1,这是您的原始信息。

这是由于CBC模式的属性而起作用的,下图显示了这种情况;

enter image description here

很高兴您在那里进行了测试。在使用之前,您应该阅读程序的所有文档,这在加密应用程序中尤为重要。

您在IV前面添加的是正确的,那里没有什么错,您只需要向站点提供IV,只需提供密文块即可。

如果需要在不使用IV的情况下解密文本,请在加密时将iv设置为默认值。

class AESCipher(object):

    def __init__(self,key): 
        self.bs = AES.block_size
        self.key = key

    def encrypt(self,raw):
        raw = self._pad(raw)
        iv = b'\0'*16 #Default zero based bytes[16]
        cipher = AES.new(self.key,AES.MODE_CBC,iv)
        return base64.b64encode(cipher.encrypt(raw.encode()))

    def _pad(self,s):
        return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)