龙空技术网

JS和Python实现AES算法

IT小明 130

前言:

眼前你们对“javascript在python中”大体比较关注,兄弟们都需要知道一些“javascript在python中”的相关内容。那么小编同时在网络上汇集了一些有关“javascript在python中””的相关知识,希望朋友们能喜欢,大家一起来了解一下吧!

1. AES原理

AES算法是典型的对称加密算法,AES原理可以学习这两篇文档:

漫画:什么是AES算法:加密算法的详细介绍与实现:或者可以看之前我整理的:AES算法原理2. 摘要ECB模式比较简单,不需要偏移量,本文都是以CBC模式为例。用JS实现AES算法(基于nodejs的crypto-js库,或者通过导入aes.js,CBC模式,Base64编码)用python实现AES算法(基于cryptodemo模块,CBC模式,16进制ASCII编码和Base64编码两种处理加密结果)加密明文均兼容中文,JS与python实现的AES算法结果一致3.JS实现AES算法3.1 基于node环境

npm install crypto-js

// test.js,Base64编码,`node test`执行const CryptoJS = require("crypto-js");var key ="0CoJUm6Qyw8W8jud";var iv = "0102030405060708";function encrypt(text){    return CryptoJS.AES.encrypt(text,CryptoJS.enc.Utf8.parse(key),{        iv:CryptoJS.enc.Utf8.parse(iv),        mode:CryptoJS.mode.CBC,        padding:CryptoJS.pad.Pkcs7    })}function decrypt(text){    var result = CryptoJS.AES.decrypt(text,CryptoJS.enc.Utf8.parse(key),{        iv:CryptoJS.enc.Utf8.parse(iv),        mode:CryptoJS.mode.CBC,        padding:CryptoJS.pad.Pkcs7    })    return result.toString(CryptoJS.enc.Utf8)}var text="小眯嘻";var encoded=encrypt(text)console.log(encoded.toString());console.log(decrypt(encoded))
3.2 不需要node环境

导入 aes.js 脚本,也能直接使用

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <title> aes.js</title></head><script src="aes.js"></script><body><script>    function encrypt(text){        return CryptoJS.AES.encrypt(text,CryptoJS.enc.Utf8.parse(key),{            iv:CryptoJS.enc.Utf8.parse(iv),            mode:CryptoJS.mode.CBC,            padding:CryptoJS.pad.Pkcs7        })    }        function decrypt(text){        var result = CryptoJS.AES.decrypt(text,CryptoJS.enc.Utf8.parse(key),{            iv:CryptoJS.enc.Utf8.parse(iv),            mode:CryptoJS.mode.CBC,            padding:CryptoJS.pad.Pkcs7        })        return result.toString(CryptoJS.enc.Utf8)    }        // const CryptoJS = require("crypto-js");    var key ="0CoJUm6Qyw8W8jud";    var iv = "0102030405060708";        var text="小眯嘻";    var encoded=encrypt(text)    console.log(encoded.toString());    console.log(decrypt(encoded))</script></body></html>
4.Python实现AES算法

pip install pycryptodome

pycryptodome 库是对 pycrypto 库的扩展

4.1 十六进制ASCII处理加密结果

from Crypto.Cipher import AESfrom binascii import b2a_hex, a2b_hex# 如果text不足16位的倍数就用空格补足为16位# 不同于JS,pycryptodome库中加密方法不做任何padding,因此需要区分明文是否为中文的情况def add_to_16(text):    pad = 16 - len(text.encode('utf-8')) % 16    text = text + pad * chr(pad)    return text.encode('utf-8')# 加密函数def encrypt(text, key, mode, iv):    text = add_to_16(text)    cryptos = AES.new(key, mode, iv)    cipher_text = cryptos.encrypt(text)    return b2a_hex(cipher_text).decode('utf-8')def decrypt(text, key, mode, iv):    cryptos = AES.new(key, mode, iv)    text = a2b_hex(text)    plain_text = cryptos.decrypt(text)    # return plain_text.decode('utf-8')    return bytes.decode(plain_text)if __name__ == '__main__':    key = '0CoJUm6Qyw8W8jud'.encode('utf-8')    mode = AES.MODE_CBC    iv = '0102030405060708'.encode('utf-8')    text = "小眯嘻的博客123"    e = encrypt(text, key, mode, iv)  # 加密    print("加密后:", e)    d = decrypt(e, key, mode, iv)  # 解密    print("解密后:", d)

encode() 和 decode() 方法用于字符串与 bytes 的互相转换。binascii 模块包含很多用来方法来转换二进制和各种ASCII编码的二进制表示法,其中 b2a_hex() 和 a2b_hex() 方法用于 bytes 与 16进制ASCII 的互相转换。

Python的内置函数 bytes() 可以将字符串str类型转换成bytes类型,必须明确encoding的参数,不可省略。而如果字符串内容都是 ASCII 字符,则可以通过直接在字符串之前添加 'b' 来构建字节串值,就能直接将一个字符串转换成 bytes 对象。同样的,bytes转为字符串,python3中的内置函数ascii()返回一个字符串对象,如果参数中有非ascii字符,会用 \u,\U,\x 来替代。

encrypt() 和 decrypt() 方法返回的结果是bytes类型。因为输出的bytes中的字节不一定能与ascii字符集对应的上,因此先将bytes转换为16进制的ASCII,便于保存输出结果。

4.2 Base64编码加密结果

python中的基本使用

# 编码>>> base64.b64encode(b'/x01') # 想象它是一张图片,编码成 base64 之后,就能进行传输b'L3gwMQ=='# 解码>>> base64.b64decode(b'L3gwMQ==') # 传输成功之后,在把解码回来变成一张图片b'/x01'

前面的AES算法中,如果将加密结果转成Base64位,

import base64from Crypto.Cipher import AESfrom binascii import b2a_hex, a2b_hex# 如果text不足16位的倍数就用空格补足为16位# 不同于JS,pycryptodome库中加密方法不做任何padding,因此需要区分明文是否为中文的情况def add_to_16_cn(text):    pad = 16 - len(text.encode('utf-8')) % 16    text = text + pad * chr(pad)    return text.encode('utf-8')# 加密函数def encrypt(text, key, mode, iv):    text = add_to_16_cn(text)    cryptos = AES.new(key, mode, iv)    cipher_text = cryptos.encrypt(text)    # return b2a_hex(cipher_text).decode('utf-8')    return base64.b64encode(cipher_text).decode('utf-8') #base编码def decrypt(text, key, mode, iv):    cryptos = AES.new(key, mode, iv)    # text = a2b_hex(text)    text = base64.b64decode(text) #base64解码    plain_text = cryptos.decrypt(text)    return plain_text.decode('utf-8')if __name__ == '__main__':    key = '0CoJUm6Qyw8W8jud'.encode('utf-8')    mode = AES.MODE_CBC    iv = '0102030405060708'.encode('utf-8')    text = "小眯嘻的博客123"    e = encrypt(text, key, mode, iv)  # 加密    print("加密后:", e)    d = decrypt(e, key, mode, iv)  # 解密    print("解密后:", d)
5.结果验证

验证一下,JS与python实现的AES算法,结果一致,且能兼容中文的。

AES_JS.png

AES_python.png

作者:小眯嘻链接:来源:简书著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

标签: #javascript在python中