一. 算法简介
- 全称高级加密标准(英文名称:Advanced Encryption Standard),在密码学中又称 Rijndael 加密法,由美国国家标准与技术研究院 (NIST)于 2001 年发布,并在 2002 年成为有效的标准,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES,已经被多方分析且广为全世界所使用,它本身只有一个密钥,即用来实现加密,也用于解密。
二. 参数定义
- key length(密钥位数,密码长度)
AES128,AES192,AES256(128 位、192 位或 256 位)
- key (密钥,密码)key指的就是密码了,
AES128
就是128位
的,如果位数不够,某些库可能会自动填充到128
。 - IV (向量)IV称为初始向量,不同的IV加密后的字符串是不同的,加密和解密需要相同的IV。
- mode (加密模式)AES分为几种模式,比如ECB,CBC,CFB等等,这些模式除了ECB由于没有使用IV而不太安全,其他模式差别并没有太明显。
- padding (填充方式)对于加密解密两端需要使用同一的PADDING模式,大部分PADDING模式为
PKCS5, PKCS7, NOPADDING
。
三.python实现
- 安装
pip install pycryptodome
- 代码实现
from Crypto.Cipher import AES
# aes加密函数
def set_aes(key, data, iv):
# 创建一个加密器
aes = AES.new(key.encode('utf-8'), mode=AES.MODE_CBC, IV=iv.encode('utf-8'))
# 将加密数据转换为字节
data_bs = data.encode('utf-8')
# 需要加密的数据必须是16的倍数
# 填充规则: 缺少数据量的个数 * chr(缺少数据量个数)
# 计算需要补位的个数
pad_len = 16 - len(data_bs) % 16
data_bs = data_bs + (pad_len * chr(pad_len)).encode('utf-8') # 补位
bs = aes.encrypt(data_bs) # 加密
return bs
# aes解密函数
def parse_aes(key, data_bs, iv):
# 创建一个加密器,需要传入秘钥,加密模式,iv
aes = AES.new(key.encode('utf-8'), mode=AES.MODE_CBC, IV=iv.encode('utf-8'))
# 解密
result = aes.decrypt(data_bs)
# 把字节转换为字符串
data = result.decode('utf-8')
return data
if __name__ == '__main__':
key = 'mhuol6ga5ta2t51a' # 秘钥,要求16位
iv = '0102030405060708' # iv,要求16位
data = '今天又是充满七万的一天' # 加密的数据
data_aes = set_aes(key, data, iv) # aes的密文
print(data_aes)
# 参数 秘钥,aes加密后的密文,iv
parse_data = parse_aes(key, data_aes, iv) # aes解密后的明文,由于有填充的信息,所以需要去掉后面的空格
print(parse_data.strip())
四. JavaScript实现
- 先安装node.js,然后安装包
// 在依赖项中添加包: --save
npm install crypto-js --save
2 .代码实现
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js')
function tripleAesEncrypt(text,aesKey,aesIv) {
var key = CryptoJS.enc.Utf8.parse(aesKey),
iv = CryptoJS.enc.Utf8.parse(aesIv),
srcs = CryptoJS.enc.Utf8.parse(text),
// CBC 加密方式,Pkcs7 填充方式
encrypted = CryptoJS.AES.encrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
function tripleAesDecrypt(encryptedData,aesKey,aesIv) {
var key = CryptoJS.enc.Utf8.parse(aesKey),
iv = CryptoJS.enc.Utf8.parse(aesIv),
srcs = encryptedData,
// CBC 加密方式,Pkcs7 填充方式
decrypted = CryptoJS.AES.decrypt(srcs, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
var text = "你好呀" // 待加密对象
var aesKey = "dfa26c64f2c2057c" // 密钥,16 倍数
var aesIv = "0123456789ABCDEF" // 偏移量,16 倍数
var encryptedData = tripleAesEncrypt(text,aesKey,aesIv)
var decryptedData = tripleAesDecrypt(encryptedData,aesKey,aesIv)
console.log("加密字符串: ", encryptedData)
console.log("解密字符串: ", decryptedData)
// 加密字符串: nMuMxLRvZGUJvh4rplwtXA==
// 解密字符串: 你好呀