本文采用 aes-cbc 模式 + Pkcs7 填充方案,在加密和解密时需要一个初始化向量(Initialization Vector, IV)和秘钥,每次加密前或解密后,使用初始化向量与明文或密文进行异或运算。
JavaScript 依赖 CryptoJS
Google Code:
https://code.google.com/archive/p/crypto-js/downloads
百度网盘:
https://pan.baidu.com/s/1Qn_8sLVNx6DRdFWBeZ0U_A
Python 依赖
- cryptography
- Crypto
- binascii
实现代码
python
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import algorithms
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
class AesCrypto(object):
def __init__(self, key):
self.key = key.encode('utf-8')[:16]
self.iv = self.key
self.mode = AES.MODE_CBC
@staticmethod
def pkcs7_padding(data):
if not isinstance(data, bytes):
data = data.encode()
padder = padding.PKCS7(algorithms.AES.block_size).padder()
padded_data = padder.update(data) + padder.finalize()
return padded_data
def encrypt(self, plaintext):
cryptor = AES.new(self.key, self.mode, self.iv)
plaintext = plaintext
plaintext = self.pkcs7_padding(plaintext)
ciphertext = cryptor.encrypt(plaintext)
return b2a_hex(ciphertext).decode('utf-8')
def decrypt(self, ciphertext):
cryptor = AES.new(self.key, self.mode, self.iv)
plaintext = cryptor.decrypt(a2b_hex(ciphertext))
return bytes.decode(plaintext).rstrip('\0')
aes = AesCrypto('ddfbccae-b4c4-11')
encrypted = aes.encrypt('恭喜你,123,gooood!')
print(encrypted)
decrypted = aes.decrypt(encrypted)
print(decrypted)
JavaScript 封装
let CryptoJS = require('../utils/aes.js')
/**
* 加密
*/
function aes_encrypt(plaintext, key, iv) {
key = CryptoJS.enc.Utf8.parse(key)
iv = CryptoJS.enc.Utf8.parse(iv)
let srcs = CryptoJS.enc.Utf8.parse(plaintext)
let encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return encrypted.ciphertext.toString()
}
/**
* 解密
*/
function aes_decrypt(ciphertext, key, iv) {
key = CryptoJS.enc.Utf8.parse(key)
iv = CryptoJS.enc.Utf8.parse(iv)
let hex_string = CryptoJS.enc.Hex.parse(ciphertext)
let srcs = CryptoJS.enc.Base64.stringify(hex_string)
let decrypt = CryptoJS.AES.decrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
decrypt = decrypt.toString(CryptoJS.enc.Utf8)
return decrypt.toString()
}
JavaScript 调用
key 和 iv 使用 16 位长度字符串
let plaintext = '恭喜你,123,goood!'
let key = "ddfbccae-b4c4-11"
let iv = "ddfbccae-b4c4-11"
let ciphertext = aes_encrypt(plaintext, key, iv)
console.log('ciphertext', ciphertext)
plaintext = aes_decrypt(ciphertext, key, iv)
console.log('plaintext', plaintext)