AES-CBC加密
整个过程key和iv必须保持一致, 在pycharm中实现需要在该文件目录下安装crypto-js, 先cd到该目录, 然后输入命令npm install crypto-js
CBC模式和ECB模式的唯一区别就是多了个iv
let CryptoJS = require('crypto-js');
## AES-CBC模式加密
let key = CryptoJS.enc.Utf8.parse('123456789qwertyu'), //密钥必须是16位,utf8编码方式
iv = CryptoJS.enc.Utf8.parse("0123456789ABCDEF"); //iv也是16位哦, utf8编码方式
function jiami(text){
let encryptedData = CryptoJS.AES.encrypt(text, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
let hexData = encryptedData.ciphertext.toString();
return hexData;
}
console.log(jiami('iloveyoubaby'));
// hexData = 5d405dde1859ed49e8eaed988b82c8bf
## AES-CBC模式解密
function jiemi(hexData){
let encryptedHexStr = CryptoJS.enc.Hex.parse(hexData), //把加密数据以Hex编码方式转成数组
encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedHexStr), //把上一步的数组以Baes64编码方式转成字符串
decryptedData = CryptoJS.AES.decrypt(encryptedBase64Str, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
let text = decryptedData.toString(CryptoJS.enc.Utf8);
return text; // 得到解密结果
}
console.log(jiemi('5d405dde1859ed49e8eaed988b82c8bf'))
那在python中又该怎么实现AES-CBC模式的加密和解密呢?
import base64
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
## 先encode是为了防止明文有中文报错, 中文utf8编码后是占3个字节<gbk编码是占2个字节>, 数字和字母是占1个字节
# 填充函数
def add_to_16(value):
while len(value.encode('utf-8')) % 16 != 0:
value += '\x00' # 补全, 明文和key都必须是16的倍数
return value.encode('utf-8')
# 加密
def AESEncrypt():
text = 'ilvoelove我爱你呀'
iv = '0123456789ABCDEF'
key = '123456789qwertyu'
aes = AES.new(key=add_to_16(key), mode=AES.MODE_CBC, iv=iv.encode())
encryptedstr = aes.encrypt(add_to_16(text)) # 加密后得到的字节数据
# 结果: b'\x8f#\x10\xeb\xf8\x13\xb4\xb5\x11\x9d\x185'
en_str = base64.b64encode(encryptedstr).decode() # 以base64编码方式解码, 得到加密字符串!
# 结果:yMQ6/gTtLURnRg1Iu2ZMiix79u8jsVHHFA2qKs28aQ=
# en_str = b2a_hex(encryptedstr).decode() # 以hex编码方式解码, 得到加密字符串
# 结果:8f2310ebf813b4b5119d183522ed993228b1efdbbc8ec5471c5036a8ab36f1a4
return en_str # 把加密后的字节数据返回
# 解密
def AESDecrypt(en_str):
iv = '0123456789ABCDEF'
key = '123456789qwertyu'
# 解密时必须重新构建aes对象
aes = AES.new(key=add_to_16(key), mode=AES.MODE_CBC, iv=iv.encode())
# 先把密文转换成字节型, 再解密, 最后把之前填充的'\x00' 去掉
decryptedstr = aes.decrypt(base64.decodebytes(en_str)).decode().strip('\x00')
# decryptedstr = aes.decrypt(a2b_hex(en_str)).decode().strip('\x00') # 对应上面的hex编码
print(decryptedstr)
if __name__ == '__main__':
en_str = AESEncrypt()
AESDecrypt(en_str)
PS : 话说 base64.b64encode(text.encode()) 和 base64.encodebytes(text.encode()) 以及 base64.b64decode(text.encode()) 和 base64.decodebytes(text.encode()) 有什么区别吗?