简介:全称高级加密标准(英文名称:Advanced Encryption Standard),在密码学中又称 Rijndael 加密法,由美国国家标准与技术研究院 (NIST)于 2001 年发布,并在 2002 年成为有效的标准,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的 DES,已经被多方分析且广为全世界所使用,它本身只有一个密钥,即用来实现加密,也用于解密。
mode支持
CBC,CFB,CTR,CTRGladman,ECB,OFB 等。
padding支持
ZeroPadding,NoPadding,AnsiX923,Iso10126,Iso97971,Pkcs7 等。
在对称与非对称的加密算法中,经常会用到三个参数:初始向量iv、加密模式mode以及填充方式padding,先介绍三个参数的含义和作用:
在密码学中,初始向量又称为初始函数,与密钥结合使用,作为加密数据的手段,它是一个固定长度的值,iv的长度取决于加密方法,通常与使用的加密密钥或密码的长度相当,一般在使用过程中会要求他是随机数或者是拟随机数,使用随机数产生的初始向量才能达到语义安全,让攻击者难以对原文一致且使用同一密钥生成的密文进行破解。
目前流行的加密和数字认证算法,都是采用块加密方式,意思就是说将加密的明文分成固定大小的数据块,然后对其执行密码算法。,从而得到密文。数据块通常采用与密钥一样的长度。加密模式在加密算法的基础上发展出来,同时也可以独立于加密算法而存在,加密模式定义了怎么样通过重复利用加密算法将大于一个数据块大小的明文转化为密文,描述了加密每一个数据块的过程,目前利用较多的加密模式有:CBC、ECB、PBCB、CFB、OFB、CTR。
块密码只能对确定长度的数据进行处理,而消息的长度通常是可变的。因此部分模式最后一块数据在加密前需要进行填充。有几种填充的方法,其中最简单的的一种就是在明文最后填充空字符以使其长度为块数据的整数倍,常见的填充方式有以下几种:PKCS7、PKCSS、ZeroPadding、ISO10126、ANSIX923。
// 引用 crypto-js 加密模块
var CryptoJS = require('crypto-js')
function tripleAesEncrypt() {
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() {
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 = "I love Python!" // 待加密对象
var aesKey = "6f726c64f2c2057c" // 密钥,16 倍数
var aesIv = "0123456789ABCDEF" // 偏移量,16 倍数
var encryptedData = tripleAesEncrypt()
var decryptedData = tripleAesDecrypt()
console.log("加密字符串: ", encryptedData)
console.log("解密字符串: ", decryptedData)
// 加密字符串: dZL7TLJR786VGvuUvqYGoQ==
// 解密字符串: I love Python!
import base64
from Cryptodome.Cipher import ARC4
def rc4_encrypt(key, t):
enc = ARC4.new(key.encode('utf8'))
res = enc.encrypt(t.encode('utf-8'))
res = base64.b64encode(res)
return res
def rc4_decrypt(key, t):
data = base64.b64decode(t)
enc = ARC4.new(key.encode('utf8'))
res = enc.decrypt(data)
return res
if __name__ == "__main__":
secret_key = '12345678' # 密钥
text = 'I love Python!' # 加密对象
encrypted_str = rc4_encrypt(secret_key, text)
print('加密字符串:', encrypted_str)
decrypted_str = rc4_decrypt(secret_key, encrypted_str)
print('解密字符串:', decrypted_str)
# 加密字符串: b'8tNVu3/U/veJR2KgyBw='
# 解密字符串: b'I love Python!'
目标网站:aHR0cDovL2p6c2MubW9odXJkLmdvdi5jbi9kYXRhL2NvbXBhbnk=
分析发现,企业数据是通过Ajax加载出来的,并且是加密数据。从以往的经验来分析,加密前的内容应该是json数据,而且也看不出数据的加密方式。因此一般的json数据可以搜索json.parse找到目标代码。
通过全局的搜索,发现一共有三处可以代码,通过调试分析,发现app.84b2e728.js便是目标文件。
在可疑代码处打上断点进行调试:
变量e就是解密后的数据,观察语句var e = JSON.parse(h(t.data)); ,直接跟进h函数,可以看到很明显的AES加密:
从上图可以发现,变量r就是加密前的数据,变量t是加密后的数据。
function h(t) {
var e = d.a.enc.Hex.parse(t)
, n = d.a.enc.Base64.stringify(e)
, a = d.a.AES.decrypt(n, f, {
iv: m,
mode: d.a.mode.CBC,
padding: d.a.pad.Pkcs7
})
, r = a.toString(d.a.enc.Utf8);
return r.toString()
}
加密模式是CBC、填充方式是pkcs7,而缺少的偏移量m、f的值,在上面可以找到。
f = d.a.enc.Utf8.parse("jo8j9wGw%6HbxfFn")
m = d.a.enc.Utf8.parse("0123456789ABCDEF")
在python中,需要引入CryptoJS,重写这个函数即可。