利用crypto-js、python实现AES 、DES前后端的加解密
前端 crypto-js aes 加解密
要用 AES 算法加密,首先我们要引入 crypto-js ,crypto-js 是一个纯 javascript 写的加密算法类库 ,可以非常方便地在 javascript 进行 MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密,我们可以采用 npm install crypto-js --save 进行下载安装,也可以直接去 GitHub下载源码~
const CryptoJS = require('crypto-js'); //引用AES源码js
const key = CryptoJS.enc.Utf8.parse("1234123412ABCDEF"); //十六位十六进制数作为密钥
const iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412'); //十六位十六进制数作为密钥偏移量
//解密方法
function Decrypt(word) {
let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
let srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
let decrypt = CryptoJS.AES.decrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
//加密方法
function Encrypt(word) {
let srcs = CryptoJS.enc.Utf8.parse(word);
let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return encrypted.ciphertext.toString().toUpperCase();
}
export default {
Decrypt ,
Encrypt
}
上面的代码中的 key 是密钥 ,iv 是密钥偏移量,这个一般是接口返回的,为了方便,我们这里就直接在这里定义了。
值得注意的是密钥的长度,由于对称解密使用的算法是 AES-128-CBC算法,数据采用 PKCS#7 填充 , 因此这里的 key 需要为16位!
接着我们定义了 解密方法Decrypt 和 加密方法 Encrypt ,最后通过 export default 将其暴露出去,方便在需要的时候进行引入~
—————————————————————————————————————————————
转载链接:https://www.jianshu.com/p/a47477e8126a
—————————————————————————————————————————————
crypto-js实现前端《AES/DES》加密,python进行对应的后端解密
一. AES加密解密
1.AES-128-CBC
Zero:数据长度不足时填充0,如果数据长度刚好合适就不填充
PKCS5:填充8字节长度的ASCII码编号为8的字符
PKCS7:(1) 数据如果长度刚好合适,就填充数据长度的字节,填充数据为ASCII码编号为数据长度的字符
(2)数据长度如果没对齐,则差n长度,就补充n长度的ASCII码编号为n的字符
分析
1.前端参数
2.前端逻辑分析
- key秘钥采用随机数生成16为字符,然后通过Crypto.enc.UTF8.parse解析成需要的key
- iv偏移量采用key进行MD5加密后取前16个字符作为偏移量
- AES加密后的数据最后再base64加密后显现的
- 数据传输时加密把key和加密后的数据传到后端
3.后端参数
4.后端逻辑分析
- 拿到随机的key字符串,然后转化为MD5,取前面16个字符作为偏移量iv
- 将前端传来的加密数据先base64解密为需要AES解密的数据
- AES解密,key,iv都时字符串
- 不同的数据填充方式,获取的最后解密的数据是不同的,需要根据不同的数据填充方式转化为最终我们需要的前端原始未加密的字符串
js前端实现加密
// n位随机数生成
function randomNum(n) {
let sString = "";
let strings = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (i = 0; i < n; i++) {
ind = Math.floor(Math.random() * strings.length);
sString += strings.charAt(ind);
}
return sString
}
//AES-128-CBC-ZeroPadding加密
function encrypt(data, key) {
iv = CryptoJS.MD5(key).toString().substring(0, 16); //取转化为md5格式的前面16位字符
key = CryptoJS.enc.Utf8.parse(key); //解析后的key
iv = CryptoJS.enc.Utf8.parse(iv); //解析后的iv
encrypted = CryptoJS.AES.encrypt(data, key, { //j加密
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
});
return encrypted.toString()
}
python后端解密
import base64
import hashlib
from Crypto.Cipher import AES, DES
class DeAesCrypt:
"""
AES-128-CBC解密
"""
def __init__(self, data, key, pad):
"""
:param data: 加密后的字符串
:param key: 随机的16位字符
:param pad: 填充方式
"""
self.key = key
self.data = data
self.pad = pad.lower()
hash_obj = hashlib.md5() # 构造md5对象
hash_obj.update(key.encode()) # 进行md5加密,md5只能对byte类型进行加密
res_md5 = hash_obj.hexdigest() # 获取加密后的字符串数据
self.iv = res_md5[:16]
@property
def decrypt_aes(self):
"""AES-128-CBC解密"""
real_data = base64.b64decode(self.data)
my_aes = AES.new(self.key, AES.MODE_CBC, self.iv)
decrypt_data = my_aes.decrypt(real_data)
return self.get_str(decrypt_data)
def get_str(self, bd):
"""解密后的数据去除加密前添加的数据"""
if self.pad == "zero": # 去掉数据在转化前不足16位长度时添加的ASCII码为0编号的二进制字符
return ''.join([chr(i) for i in bd if i != 0 ])
elif self.pad == "pkcs7": # 去掉pkcs7模式中添加后面的字符
return ''.join([chr(i) for i in i > 32]) # 此处报错,在我环境
else:
return "不存在此种数据填充方式"
二、 DES加密解密
1.DES-128-CBC模式
分析
1)前端参数
2)前端逻辑分析
- key秘钥采用随机数生成8为字符,然后通过Crypto.enc.UTF8.parse解析成需要的key
- iv偏移量采用key进行base64加密后取前8个字符作为偏移量
- DES加密后的数据最后再base64加密后显现的
- 数据传输时加密把key和加密后的数据传到后端
3)后端参数
4.后端逻辑分析
- 拿到随机的key字符串,然后转化为base64,取前面8个字符作为偏移量iv
- 将前端传来的加密数据先base64解密为需要DES解密的数据
- DES解密,key,iv都时字符串
- 不同的数据填充方式,获取的最后解密的数据是不同的,需要根据不同的数据填充方式转化为最终我们需要的前端原始未加密的字符串
js前端实现加密
// n位随机数生成
function randomNum(n) {
let sString = "";
let strings = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
for (i = 0; i < n; i++) {
ind = Math.floor(Math.random() * strings.length);
sString += strings.charAt(ind);
}
return sString
}
// DES-128-CBC-Zero-crypt
function desZeroEncrypt(data, key) {
let iv = CryptoJS.enc.Utf8.parse(key);
iv = CryptoJS.enc.Base64.stringify(iv).toString().substring(0,8);//base64加密取前8位
iv = CryptoJS.enc.Utf8.parse(iv);
key = CryptoJS.enc.Utf8.parse(key);
return CryptoJS.DES.encrypt(data, key, {
iv: iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
}).toString();
}
python 后端解密
import base64
import hashlib
from Crypto.Cipher import AES, DES
class DeDesCrypt:
"""
DES-128-CBC解密
"""
def __init__(self, data, key, pad):
"""
:param data: 加密后的字符串,在解密是需要先进行base64解密后才行
:param key: 随机的8位字符
:param pad: 填充方式
"""
self.key = key
self.data = base64.b64decode(data.encode())
self.pad = pad.lower()
self.iv = base64.b64encode(key.encode())[0:8]
@property
def decrypt_des(self):
"""DES-128-CBC解密"""
my_des = DES.new(self.key, AES.MODE_CBC, self.iv)
decrypt_data = my_des.decrypt(self.data)
return self.get_str(decrypt_data)
def get_str(self, bd):
"""解密后的数据去除加密前添加的数据"""
if self.pad == "zero": # 去掉数据在转化前不足8位长度时添加的ASCII码为0编号的二进制字符
return ''.join([chr(i) for i in bd if i != 0])
elif self.pad == "pkcs7": # 去掉pkcs7模式中添加后面的字符
return ''.join([chr(i) for i in i > 32])
else:
return "不存在此种数据填充方式"
—————————————————————————————————————————————
原文链接:https://blog.csdn.net/hl120841/article/details/105278277
CryptoJS aes加密,需key 和偏移量 iv
function getAesString(data,key,iv){//加密
var key = CryptoJS.enc.Latin1.parse(key);
var iv = CryptoJS.enc.Latin1.parse(iv);
var srcs = CryptoJS.enc.Utf8.parse(data);
var encrypted = CryptoJS.AES.encrypt(srcs,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return encrypted;
}
function getDAesString(encrypted,key,iv){//解密
var key = CryptoJS.enc.Latin1.parse(key);
var iv = CryptoJS.enc.Latin1.parse(iv);
var decrypted = CryptoJS.AES.decrypt(encrypted,key,
{
iv:iv,
mode:CryptoJS.mode.CBC,
padding:CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}
function getAES(){ //加密
var data = "123456";//明文
var key = 'aaaa'; //密钥
var iv = 'bbbb';
var encrypted = getAesString(data,key,iv); //密文
var enstr = CryptoJS.enc.Base64.stringify(encrypted.ciphertext);//encrypted.toString();
// document.getElementById("encrypted").innerHTML = encrypted;
}
// function getDAes(){//解密
// var encrypted = document.getElementById("encrypted").innerHTML; //密文
// var key = '1234567812345678';
// var iv = 'Pkcs7';
// var decryptedStr = getDAesString(encrypted,key,iv);
// document.getElementById("decrypted").innerHTML = decryptedStr;
// };
getAES();
var key = CryptoJS.enc.Latin1.parse(key);
var iv = CryptoJS.enc.Latin1.parse(iv);
key 和iv 编码均为CryptoJS.enc.Latin1.parse
参考资料: http://wenku.baidu.com/link?url=aVGnTYLZxpssQpXPNfArG-bHpq-GYALUXCTeDwQWUZyIZGitimtmcr25elkem8cAPs4JjYIc3P8q7OTTjidOHWxM1NJDRIH2wuQvZkHgaYO
—————————————————————————————————————————————
原文链接:https://blog.csdn.net/u010200636/article/details/53004754
python3.6执行AES加密及解密方法
python版本:3.6.5
首先安装pycryptodome
# pip install pycryptodome
加密方式特别简单,代码如下:
方式一:补0
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
补0方式(ECB加密)
"""
import base64
from Crypto.Cipher import AES
# 补足字符串长度为16的倍数
def add_to_16(s):
while len(s) % 16 != 0:
s += '\0'
return str.encode(s) # 返回bytes
key = '1234567890123456' # 密钥长度必须为16、24或32位,分别对应AES-128、AES-192和AES-256
text = 'abcdefg' # 待加密文本
aes = AES.new(str.encode(key), AES.MODE_ECB) # 初始化加密器,本例采用ECB加密模式
encrypted_text = str(base64.encodebytes(aes.encrypt(add_to_16(text))), encoding='utf8').replace('\n', '') # 加密
decrypted_text = str(aes.decrypt(base64.decodebytes(bytes(encrypted_text, encoding='utf8'))).rstrip(b'\0').decode("utf8")) # 解密
print('加密值:', encrypted_text)
print('解密值:', decrypted_text)
结果为:
方式二:pkcs5
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
pkcs5补码方式(ECB加密)
"""
import base64
from Crypto.Cipher import AES
# 补足字符串长度为16的倍数
def add_to_16(s):
while len(s) % 16 != 0:
s += (16 - len(s) % 16) * chr(16 - len(s) % 16)
return str.encode(s) # 返回bytes
key = '1234567890123456' # 密钥长度必须为16、24或32位,分别对应AES-128、AES-192和AES-256
text = 'abcdefg' # 待加密文本
aes = AES.new(str.encode(key), AES.MODE_ECB) # 初始化加密器,本例采用ECB加密模式
encrypted_text = str(base64.encodebytes(aes.encrypt(add_to_16(text))), encoding='utf8').replace('\n', '') # 加密
decrypted_text = aes.decrypt(base64.decodebytes(bytes(encrypted_text, encoding='utf8'))).decode("utf8") # 解密
decrypted_text = decrypted_text[:-ord(decrypted_text[-1])] # 去除多余补位
print('pkcs5加密值:', encrypted_text)
print('pkcs5解密值:', decrypted_text)
结果为:
两种方式加密后的值是不一样的,解密方式也是不一样的。
个人开发、IT常用工具网站 https://www.huatools.com/
功能有 JSON格式化、XML格式化、URL格式化、Unix时间戳、Unicode转中文等。
原文链接:https://blog.csdn.net/hh775313602/article/details/78991340
python3.6 实现AES加密、解密(改版)
用pyCryptodome模块带的aes先将秘钥,以及要加密的文本填充为16位,随后对aes产生的字节码进行base64位编码,转为字符串的形式即可,解密思想逆过来即可。先逆向解密base64成bytes,执行解密密并转码返回str,将多余位数的’\0’替换为空。
#AES-demo
import base64
from Crypto.Cipher import AES
'''
采用AES对称加密算法
'''
# str不是16的倍数那就补足为16的倍数
def add_to_16(value):
while len(value) % 16 != 0:
value += '\0'
return str.encode(value) # 返回bytes
#加密方法
def encrypt_oracle():
# 秘钥
key = '123456'
# 待加密文本
text = 'abc123def456'
# 初始化加密器
aes = AES.new(add_to_16(key), AES.MODE_ECB)
#先进行aes加密
encrypt_aes = aes.encrypt(add_to_16(text))
#用base64转成字符串形式
encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8') # 执行加密并转码返回bytes
print(encrypted_text)
#解密方法
def decrypt_oralce():
# 秘钥
key = '123456'
# 密文
text = 'qR/TQk4INsWeXdMSbCDDdA=='
# 初始化加密器
aes = AES.new(add_to_16(key), AES.MODE_ECB)
#优先逆向解密base64成bytes
base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8'))
#执行解密密并转码返回str
decrypted_text = str(aes.decrypt(base64_decrypted),encoding='utf-8').replace('\0','')
print(decrypted_text)
if __name__ == '__main__':
# encrypt_oracle()
decrypt_oralce()
原文链接:https://sssyyy.blog.csdn.net/article/details/79026128
Python之AES加密遇到的一些坑以及解决方法
报错信息:TypeError: Object type <class ‘str’> cannot be passed to C code
之前用Python写AES/CBC/PKCS5Padding加密, 写好了1.0版本之后只是这样的:
报错原因是因为秘钥和偏移量里也需要用utf-8编码一下,所以在加密时候, 把加密内容转一下就好了。
完整代码如下:
import base64
import binascii
import re
from Crypto.Cipher import AES
class AESCBC:
def __init__(self):
self.key = 'msunsoftalphaicd'.encode('utf-8') # 定义key值
self.mode = AES.MODE_CBC
self.bs = 16 # block size
self.PADDING = lambda s: s + (self.bs - len(s) % self.bs) * chr(self.bs - len(s) % self.bs)
# 加密
def encrypt(self, text):
generator = AES.new(self.key, self.mode, self.key) # 这里的key 和IV 一样 ,可以按照自己的值定义
crypt = generator.encrypt(self.PADDING(text).encode('utf-8'))
crypted_str = base64.b64encode(crypt) #输出Base64
# crypted_str = binascii.b2a_hex(crypt) # 输出Hex
result = crypted_str.decode()
return result
# 解密
def decrypt(self, text):
generator = AES.new(self.key, self.mode, self.key)
text += (len(text) % 4) * '='
decrpyt_bytes = base64.b64decode(text) #输出Base64
# decrpyt_bytes = binascii.a2b_hex(text) # 输出Hex
meg = generator.decrypt(decrpyt_bytes)
# 去除解码后的非法字符
try:
result = re.compile('[\\x00-\\x08\\x0b-\\x0c\\x0e-\\x1f\n\r\t]').sub('', meg.decode())
except Exception:
result = '解码失败,请重试!'
return result
if __name__ == '__main__':
a = AESCBC()
print(a.encrypt('1'))
print(a.decrypt(a.encrypt('1')))
原文链接:https://blog.csdn.net/wangziyang777/article/details/104982823
其他相关资料:
python3 实现AES加密、解密 、及报错误处理
Python-AES加密-CBC模式-PKCS7填充
AES/CBC/PKCS7加密 以及PKCS5加密简单实用
转载只为于方便自己查阅、学习,不做任何商业用途。
更多推荐
所有评论(0)