如何用python实现js的AES加密和解密

2023-05-2615:34:36编程语言入门到精通Comments2,030 views字数 3208阅读模式

什么是AES加密

AES加密(Advanced Encryption Standard)是一种对称加密算法,它只使用一个密钥进行加密和解密。该算法可用于多种模式,包括ECB、CBC、CFB、OFB和CTR等,其中最常用的是CBC模式。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

为什么要用Python实现js的AES加密解密

举个例子,我们因为学习交流或其他原因,需要获取某个网站的某个api的数据,当我们查看数据内容时,发现是这样的格式文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

如何用python实现js的AES加密和解密
prompt: "U2FsdGVkX18ysXWhT/IUHhE7TatRnKt7oMBu4hD0cz8="

这样的数据显然是经过加密的,发送到服务端后再进行解密。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

我们找到加密代码所在的位置文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

如何用python实现js的AES加密和解密
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实现,推荐这种方法。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

AES加密库

能够使用aes算法的python库有cryptopycryptopycryptodomexpycryptodome等,但是因为各种原因,很多库已经不再维护了,目前推荐使用且一直在维护的库为pycryptodome,且其调用方法都是相同的。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

pip install pycryptodome -i https://pypi.tuna.tsinghua.edu.cn/simple

加密解密方法文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

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)

上述代码的输出结果为文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

要加密的字符串:data
加密后的字符串:b'hAoMQT3Kbn3MWHgyFHlQUw=='
解密后的字符串:b'data\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c'

python加密和js加密的异同

当你想调用python的aes加密方法,去实现和js相同的加密内容是,你就会发现这样一些问题文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

  1. python需要用到iv,js怎么没传iv参数呢?
  2. python中的key和iv的长度必须为16、24或32,js中怎么什么长度都可以呢?
  3. 加密后的密文怎么不一样呢?
  4. python加密后的密文长度怎么和js的不一样长呢?

我们进行一一解答:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

  1. AES默认使用CBC加密,CBC加密是要用到iv的,js不需要必传iv参数的原因是,当不传此参数是,js会自动生成。
  2. 当key和iv的长度不是指定长度时,需要进行补齐,python需要手动补齐,js进行了自动补齐。
  3. 每次加密后的密文时不一样的,这是因为js在加密时会添加随机salt,但是解密后的密文是相同的。
  4. js在加密时会添加Salted__和随机salt,使得加密长度比用python加密长。

用python实现js的AES加密

根据以上种种,直接用python的encrypt方法是得不到js的密文的。但是幸运的是有这样一个库,实现了很多语言的AES通用加密——aes-everything。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

AES Everywhere - Cross Language Encryption Library (Bash, C#, Dart, GoLang, Java, JavaScript, PHP, Python, Ruby, Swift)文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

pip install aes-everything -i https://pypi.tuna.tsinghua.edu.cn/simple

方法如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

加密方法文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

from AesEverywhere import aes256
data = "data"
key = "012345678"
encrypted = aes256.encrypt(data, key)

解密方法文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

from AesEverywhere import aes256
data = "U2FsdGVkX1+I0zYbay/n9fgynjYWwpC9fPRBQR1z0j8="
key = "012345678"
encrypted = aes256.encrypt(data, key)

ECB加密解密方法文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

aes-everything没有提供ECB模式的加解密方法,我们将上述模式(CBC模式)的代码稍微进行魔改即可,如下文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

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加密解密的方法,目前网上的其他教程都没有正确说明,本文解答了疑惑,给出正确代码,建议有需要的同学收藏本文。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/ymba/42611.html

  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/ymba/42611.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定