用python解密crypto-js中AES加密的密码串

最近爬取京东后台数据,遇到一个棘手问题,京东后台的手机号中间4位是****隐藏的,提供一个点击查看按钮,实则是一个查询按钮,但返回的是一串加密串:
在这里插入图片描述
点击查看后我们看一下返回数据:
在这里插入图片描述
我们看到,他接口返回的是一个加密串,不用想,肯定是后台返回加密串,在前端进行解密然后显示在页面非隐藏的手机号,那么肯定是js渲染的,我们先找到并分析js代码:

 $.getJSON("/order/json/phoneSensltiveInfo", data, function (data) {
                if (data.success) {
                    if (data.model) {
                        if (data.model.phone) {
                            $("#tel").html(htm(data.model.phone));
                            $("#tel").next().hide();
                        }

我们可以看到,通过ajax请求到的加密的手机号,是在前端js通过一个htm()的函数进行解密的,那么我们来看下这个函数:
~
~
~
找了好久没找到,算了,直接在控制台打印出来:
在这里插入图片描述
通过分析代码:

function htm(p){
var key=CryptoJS.enc.Utf8.parse("5a8f3244786ea9b8");
var decrypt=CryptoJS.AES.decrypt(p,key,{mode:CryptoJS.mode.ECB,padding:CryptoJS.pad.Pkcs7});
return CryptoJS.enc.Utf8.stringify(decrypt).toString()}"

我们可以知道,这个加密规则是js 内库中的crypto-js 以AES的方式进行加密的,查阅相关资料我们知道,这个加密规则是对称加密,且可逆的,也就是可以解密的,并且我们在js 中可以看到加密使用的秘钥key = “5a8f3244786ea9b8”

好,到这里我们已经成功了一半了,接下来就是解密了,我们python中也有相关第三方库的,下面直接贴代码:


#coding=utf-8
#AES-demo  AES/ECB/PKCS5|Zero
#ECB不安全.建议CBC

import base64
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex

def ByteToHex( bins ):
    """
    Convert a byte string to it's hex string representation e.g. for output.
    """
    return ''.join( [ "%02X" % x for x in bins ] ).strip()


'''
采用AES对称加密算法
'''
# str不是16的倍数那就补足为16的倍数. ZeroPadding

'''
    在PKCS5Padding中,明确定义Block的大小是8位
    而在PKCS7Padding定义中,对于块的大小是不确定的,可以在1-255之间
    PKCS #7 填充字符串由一个字节序列组成,每个字节填充该字节序列的长度。
    假定块长度为 8,数据长度为 9,
    数据: FF FF FF FF FF FF FF FF FF
    PKCS7 填充: FF FF FF FF FF FF FF FF FF 01 01 01 01 01 01 01   ?应该是填充01
    
    python3:填充bytes(这个说法不对,AES的参数是字符串,不是byte)
    length = 16 - (len(data) % 16)
    data += bytes([length])*length
 
    python2:填充字符串
    length = 16 - (len(data) % 16)
    data += chr(length)*length
    
    pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)
    unpad = lambda s : s[0:-ord(s[-1])]
'''
def add_to_16(value):
    while len(value) % 16 != 0:
        value += '\0'
    return str.encode(value)  # 返回bytes


def ZeroPadding(value,bs):
    while len(value) % bs != 0:
        value += '\0'
    return str.encode(value)  # 返回bytes

def PKCS7Padding(value,bs):
    pad = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)#PKS7
    return str.encode(pad(value)) # 返回bytes

def PKCS7UnPadding(value):
    #value = value[:-value[-1]]
    unpad = lambda s : s[0:-ord(s[-1])]  #获得数据的长度,截取
    return unpad(value)

#加密方法
def encrypt_oracle():
    # 秘钥
    key = '5a8f3244786ea9b8'
    # 待加密文本
    text = '18979034826'
    # 初始化加密器
    aes = AES.new(add_to_16(key), AES.MODE_ECB)
    bs = AES.block_size
    pad2 = lambda s: s + (bs - len(s) % bs) * chr(bs - len(s) % bs)#PKS7 就是pkcs7padding

    #先进行aes加密
    #Zeropadding
    #encrypt_aes = aes.encrypt(add_to_16(text))
    #Pkcs7 padding
    encrypt_aes = aes.encrypt(str.encode(pad2(text)))
    #转为hex
    print(ByteToHex(encrypt_aes))    #转为字符串
    print(b2a_hex(encrypt_aes))      #b''
    #用base64转成字符串形式
    encrypted_text = str(base64.encodebytes(encrypt_aes), encoding='utf-8')  # 执行加密并转码返回bytes
    print(encrypted_text)
    #和js的 结果相同 http://tool.chacuo.net/cryptaes
    return encrypted_text

#解密方法
def decrypt_oralce(text):
    # 秘钥
    key = '5a8f3244786ea9b8'
    # 密文

    # 初始化加密器
    aes = AES.new(add_to_16(key), AES.MODE_ECB)
    #优先逆向解密base64成bytes
    base64_decrypted = base64.decodebytes(text.encode(encoding='utf-8'))
    #
    decrypted_text = str(aes.decrypt(base64_decrypted),encoding='utf-8') # 执行解密密并转码返回str
    unpad = lambda s : s[0:-ord(s[-1])]    #pkcs7unpadding比较简单.
    print(unpad(decrypted_text))

if __name__ == '__main__':
    en=encrypt_oracle()
    decrypt_oralce(en)

代码很详细,复制直接可运行使用的,测试结果:
在这里插入图片描述
到这里就成功的将京东加密的手机号用python进行解密了,大功告成。

本次解密过程差不多花了一个星期的时间琢磨和查阅相关资料,走了很多弯路,希望可以给遇到同样场景的朋友们提供参考,少走弯路,如果有其他问题,在下方评论,看到了随时回复。

参考链接:https://blog.csdn.net/laputa73/article/details/80476005

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

初夏0811

你的鼓励将是我创作最大的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值