什么是AES加密
AES加密(Advanced Encryption Standard)是一种对称加密算法,它只使用一个密钥进行加密和解密。该算法可用于多种模式,包括ECB、CBC、CFB、OFB和CTR等,其中最常用的是CBC模式。
为什么要用Python实现js的AES加密解密
举个例子,我们因为学习交流或其他原因,需要获取某个网站的某个api的数据,当我们查看数据内容时,发现是这样的格式
prompt: "U2FsdGVkX18ysXWhT/IUHhE7TatRnKt7oMBu4hD0cz8="
这样的数据显然是经过加密的,发送到服务端后再进行解密。
我们找到加密代码所在的位置
const Uu = ju
, o2 = "__CRYPTO_SECRET__I>EO)$__M*&.fsee";
function Oh(e) {
const t = JSON.stringify(e);
return Uu.AES.encrypt(t, o2).toString()
}
可以看到数据是进行了AES加密。想要实现同样的加密/解密,第一种方法是使用python运行js代码,这种方法需要编译js代码,执行起来繁琐、易出错;第二种就是直接使用python实现,推荐这种方法。
AES加密库
能够使用aes算法的python库有crypto
、pycrypto
、pycryptodomex
、pycryptodome
等,但是因为各种原因,很多库已经不再维护了,目前推荐使用且一直在维护的库为pycryptodome
,且其调用方法都是相同的。
pip install pycryptodome -i https://pypi.tuna.tsinghua.edu.cn/simple
加密解密方法
import base64
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
def aes_encrypt(data, key, iv):
cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
res = base64.b64encode(
cipher.encrypt(pad(data.encode(), AES.block_size, style="pkcs7"))
)
return res
def aes_decrypt(data, key, iv):
cipher = AES.new(key.encode(), AES.MODE_CBC, iv.encode())
res = cipher.decrypt(base64.b64decode(data))
return res
if __name__ == "__main__":
data = "data"
print("要加密的字符串:", data)
key = "0123456789abcdef"
iv = "0123456789abcdef"
en = aes_encrypt(data, key, iv)
print("加密后的字符串:", en)
de = aes_decrypt(en, key, iv)
print("解密后的字符串:", de)
上述代码的输出结果为
要加密的字符串:data
加密后的字符串:b'hAoMQT3Kbn3MWHgyFHlQUw=='
解密后的字符串:b'datax0cx0cx0cx0cx0cx0cx0cx0cx0cx0cx0cx0c'
python加密和js加密的异同
当你想调用python的aes加密方法,去实现和js相同的加密内容是,你就会发现这样一些问题
iv
,js怎么没传iv
参数呢?我们进行一一解答:
Salted__
和随机salt,使得加密长度比用python加密长。用python实现js的AES加密
根据以上种种,直接用python的encrypt
方法是得不到js的密文的。但是幸运的是有这样一个库,实现了很多语言的AES通用加密——aes-everything。
AES Everywhere - Cross Language Encryption Library (Bash, C#, Dart, GoLang, Java, JavaScript, PHP, Python, Ruby, Swift)
pip install aes-everything -i https://pypi.tuna.tsinghua.edu.cn/simple
方法如下
加密方法
from AesEverywhere import aes256
data = "data"
key = "012345678"
encrypted = aes256.encrypt(data, key)
解密方法
from AesEverywhere import aes256
data = "U2FsdGVkX1+I0zYbay/n9fgynjYWwpC9fPRBQR1z0j8="
key = "012345678"
encrypted = aes256.encrypt(data, key)
ECB加密解密方法
aes-everything没有提供ECB模式的加解密方法,我们将上述模式(CBC模式)的代码稍微进行魔改即可,如下
def aes256_ecb_encrypt(raw, passphrase):
salt = aes256.Random.new().read(8)
key, iv = aes256.__derive_key_and_iv(passphrase, salt)
cipher = aes256.AES.new(key, aes256.AES.MODE_ECB)
return base64.b64encode(
b"Salted__" + salt + cipher.encrypt(aes256.__pkcs7_padding(raw))
)
def aes256_ecb_decrypt(enc, passphrase):
ct = base64.b64decode(enc)
salted = ct[:8]
if salted != b"Salted__":
return ""
salt = ct[8:16]
key, iv = aes256.__derive_key_and_iv(passphrase, salt)
cipher = aes256.AES.new(key, aes256.AES.MODE_ECB)
return aes256.__pkcs7_trimming(cipher.decrypt(ct[16:]))
总结
在本篇文章中,我们介绍了如何用python实现js的AES加密解密的方法,目前网上的其他教程都没有正确说明,本文解答了疑惑,给出正确代码,建议有需要的同学收藏本文。