使用PyCrypto AES 256加密和解密

发布于 2021-02-02 23:15:14

我正在尝试使用PyCrypto构建两个接受两个参数的函数:消息和密钥,然后对消息进行加密/解密。

我在网络上找到了几个链接可以帮助我,但是每个链接都有缺陷:

在codekoala上的此代码使用了os.urandom,PyCrypto不建议这样做。

此外,我不能保证给函数的键具有预期的确切长度。我该怎么做才能做到这一点?

另外,有几种模式,推荐哪种?我不知道该怎么用:/

最后,IV到底是什么?我可以提供不同的IV进行加密和解密,还是返回不同的结果?

到目前为止,这是我所做的:

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

BLOCK_SIZE=32

def encrypt(message, passphrase):
    # passphrase MUST be 16, 24 or 32 bytes long, how can I do that ?
    IV = Random.new().read(BLOCK_SIZE)
    aes = AES.new(passphrase, AES.MODE_CFB, IV)
    return base64.b64encode(aes.encrypt(message))

def decrypt(encrypted, passphrase):
    IV = Random.new().read(BLOCK_SIZE)
    aes = AES.new(passphrase, AES.MODE_CFB, IV)
    return aes.decrypt(base64.b64decode(encrypted))
关注者
0
被浏览
118
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    这是我的实现,并通过一些修复为我工作,并用32字节和iv到16字节增强了密钥和秘密短语的对齐方式:

    import base64
    import hashlib
    from Crypto import Random
    from Crypto.Cipher import AES
    
    class AESCipher(object):
    
        def __init__(self, key): 
            self.bs = AES.block_size
            self.key = hashlib.sha256(key.encode()).digest()
    
        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 decrypt(self, enc):
            enc = base64.b64decode(enc)
            iv = enc[:AES.block_size]
            cipher = AES.new(self.key, AES.MODE_CBC, iv)
            return self._unpad(cipher.decrypt(enc[AES.block_size:])).decode('utf-8')
    
        def _pad(self, s):
            return s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)
    
        @staticmethod
        def _unpad(s):
            return s[:-ord(s[len(s)-1:])]
    


  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    当输入的长度不是BLOCK_SIZE的倍数时,可能需要以下两个函数来填充(加密时)和取消填充(解密时)。

    BS = 16
    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS) 
    unpad = lambda s : s[:-ord(s[len(s)-1:])]
    

    所以你要问密钥的长度?你可以使用密钥的md5sum而不是直接使用它。

    而且,根据我使用PyCrypto的经验,在输入相同的情况下,IV用于混合加密输出,因此将IV选择为随机字符串,并将其用作加密输出的一部分,然后用它来解密消息。

    这是我的实现,希望它将对你有用:

    import base64
    from Crypto.Cipher import AES
    from Crypto import Random
    
    class AESCipher:
        def __init__( self, key ):
            self.key = key
    
        def encrypt( self, raw ):
            raw = 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 ) ) 
    
        def decrypt( self, enc ):
            enc = base64.b64decode(enc)
            iv = enc[:16]
            cipher = AES.new(self.key, AES.MODE_CBC, iv )
            return unpad(cipher.decrypt( enc[16:] ))
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看