AES加密有5种方式,分别是ECB, CBC, CTR, CFB, OFB
从安全性上来看CBC的安全性是最高的,因此本篇文章只讨论CBC模式
CBC加密需要key(密钥)和iv(偏移量)
密钥长度需要为8的倍数,通常只会用16,24,32其中的一种,其中32位长度安全性相比于其他两种更高.
偏移量长度需要位16
利用Crypto模块实现
python3需要安装pycryptodome
pip install pycryptodome
注意: windows环境下可能会有找不到Crypto的情况,这里有个小BUG,windows环境下安装完pycryptodome后在你python的根目录下如:
Python\Python36\Lib\site-packages
里面有一个文件夹叫做crypto,将首字母小写c改成大写C即可解决.
实现代码(CBC模式):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
| from Crypto.Cipher import AES from binascii import b2a_hex, a2b_hex
class AESsys(object): def __init__(self, key, iv): """ 密钥和偏移量 :param key:密钥:长度需要大于16,满足8的倍数 :param iv:偏移量 """ if len(key) in [16, 24, 32]: self.key = key else: raise Exception(f"密钥字符串长度需要在[16, 24, 32]中, 当前长度: key={key}, len={len(key)}") if len(iv) in [16]: self.iv = iv else: raise Exception(f"偏移量字符串长度需要在[16]中, 当前长度: key={iv}, len={len(iv)}")
@staticmethod def _add_to_16(text): if len(text.encode('utf-8')) % 16: add = 16 - (len(text.encode('utf-8')) % 16) else: add = 0 text = text + ('\0' * add) return text.encode('utf-8')
def aes_cbc_encrypt(self, text): key = self.key.encode('utf-8') mode = AES.MODE_CBC iv = self.iv.encode('utf-8') text = self._add_to_16(text) cryptos = AES.new(key, mode, iv) cipher_text = cryptos.encrypt(text) return b2a_hex(cipher_text)
def aes_cbc_decrypt(self, text): key = self.key.encode('utf-8') iv = self.iv.encode('utf-8') mode = AES.MODE_CBC cryptos = AES.new(key, mode, iv) plain_text = cryptos.decrypt(a2b_hex(text)) return bytes.decode(plain_text).rstrip('\0')
if __name__ == '__main__': message = "helloworld" aes = AESsys('111111111111111111111111', '1111111111111111') e = aes.aes_cbc_encrypt(message).decode() print("加密:", e) d = aes.aes_cbc_decrypt(e) print("解密:", d)
|
参考文章