逆向加密模块总结

admin 2024年12月16日10:27:01评论3 views字数 11873阅读39分34秒阅读模式

安全君呀设为"星标️"

第一时间收到文章更新

声明: 安全君呀 公众号文章中的技术只做研究之用,禁止用来从事非法用途,如有使用文章中的技术从事非法活动,一切后果由使用者自负,与本公众号无关。

文章声明:本篇文章内容部分选取网络,如有侵权,请告知删除。

一 逆向加密模块

1,Python中运行JS代码

1.1  解决中文乱码或者报错问题

import subprocess            from functools import partial            subprocess.Popen = partial(subprocess.Popen, encoding='utf-8')            import execjs            

1.2 常用函数

print(execjs.get().name) # 获取js代码执行环境            res = execjs.eval(js)# 执行一段js代码            #先编译            jj = execjs.compile("""function an(a, b){            return a + b}            """)            # call() 运行代码中的xxx函数. 后续的参数是xxx的参数            ret = jj.call("an", 10, 20)            #读取js文件            f = open("01.js",mode="r",encoding="utf-8")            js_code = f.read()            obj = re.compile(r"window._INIT_STATE__ = (?P.*?);",re.S) # 正则表达式              code = obj.search(js_code).group("code") #匹配正则表达式              print(type(code))#这里的code是字符串              # execjs这个库会把运行的结果自动转化成对象              result = execjs.eval(code)# 拿到的是一个JS代码运行的结果              print(result) #是个字典,Python会自动转换成字典              print(type(result)) # dict              

2,CryptoJS加密特征

function b(a, b) {              var c = CryptoJS.enc.Utf8.parse(b)              , d = CryptoJS.enc.Utf8.parse("0102030405060708")              , e = CryptoJS.enc.Utf8.parse(a)              , f = CryptoJS.AES.encrypt(e, c, {              iv: d,              mode: CryptoJS.mode.CBC              });              return f.toString()              }              #转换为UTF8              CryptoJS.enc.Utf8              # 转换为base64              CryptoJS.enc.Base64              

3,RAS加密特征

setMaxDigits,              RSAKeyPair,              encryptedString              

4,md5加密解密

from hashlib import md5              obj = md5()              obj.update("alex".encode("utf-8"))              # obj.update("wusir".encode('utf-8'))# 可以添加多个被加密的内容              bs = obj.hexdigest()              print(bs)              # 加盐              from hashlib import md5              salt = "我是盐.把我加进去就没人能破解了"              obj = md5(salt.encode("utf-8"))# 加盐              obj.update("alex".encode("utf-8"))              bs = obj.hexdigest()              print(bs)              

5,傻系列加密

sha1,sha256,sha512用法跟md5一样

from hashlib import sha1, sha256              sha = sha256(b'salt')              sha.update(b'alex')              print(sha.hexdigest())              

6,URLencode

from urllib.parse import quote, unquote, quote_plus, unquote_plus, urlencode              # 单独编码字符串 用 quote              wq = "米饭怎么吃"              print(quote(wq))# %E7%B1%B3%E9%A5%AD%E6%80%8E%E4%B9%88%E5%90%83              print(quote(wq, encoding="gbk")) # %C3%D7%B7%B9%D4%F5%C3%B4%B3%D4              # 多个数据统一进行编码 用urlencode ,比如字典进行编码              dic = {              "wq": "米饭怎么吃",              "new_wq": "想怎么吃就怎么吃"              }              print(urlencode(dic))# wq=%E7%B1%B3%E9%A5%AD%E6%80%8E%E4%B9%88%E5%90%83&new_wq=%E6%83%B3%E6%80%8E%E4%B9%88%E5%90%83%E5%B0%B1%E6%80%8E%E4%B9%88%E5%90%83              print(urlencode(dic, encoding="utf-8"))# 也可以指定字符集              # 一个完整的url编码过程              base_url = "http://www.baidu.com/s?"              params = {              "wd": "大王"              }              url = base_url + urlencode(params)              print(url)# http://www.baidu.com/s?wd=%E5%A4%A7%E7%8E%8B              #解码              s = "http://www.baidu.com/s?wd=%E5%A4%A7%E7%8E%8B"              print(unquote(s))# http://www.baidu.com/s?wd=大王              print(quote("a /b/c=", safe=""))# 传递safe=""可以保持和浏览器一致              print(quote_plus("a /b/c="))              

7,base64编码

import base64              bs = "我要吃饭".encode("utf-8")              # 把字节转化成b64              print(base64.b64encode(bs).decode())              # 把b64字符串转化成字节              s = "5oiR6KaB5ZCD6aWt"              print(base64.b64decode(s).decode("utf-8"))              #base64报错问题              import base64              s = "ztKwrsTj0b0"              bb = base64.b64decode(s)              print(bb)              此时运行出现以下问题              Traceback (most recent call last):              File "D:/PycharmProjects/rrrr.py", line 33, inbb = base64.b64decode(s)        File "D:Python38libbase64.py", line 87, in b64decode        return binascii.a2b_base64(s)        binascii.Error: Incorrect padding        # 解决办法        s = "ztKwrsTj0b0"        s += ("=" * (4 - len(s) % 4))        print("填充后", s)        bb = base64.b64decode(s).decode("gbk")        print(bb)        # 注意事项        由于标准的Base64编码后可能出现字符+和/,但是这两个字符在URL中就不能当做参数传递,所以就出现了Base64URL,下面是它们的区别:        1. Base64编码后出现的+和/在Base64URL会分别替换为-和_        2. Base64编码中末尾出现的=符号用于补位,这个字符和queryString中的key=value键值对会发生冲突,所以在Base64URL中=符号会被省略,去掉=后怎么解码呢?因为Base64是把3个字节变为4个字节,所以,Base64编码的长度永远是4的倍数,因此,需要加上=把Base64字符串的长度变为4的倍数,就可以正常解码了。        我们的应对方案:        在处理base64的时候.如果遇到了没有+和/的情况. 可以采用下面的方案来替换掉+和/        b64 = base64.b64decode(mi, b"-_")        

8,AES加密

1,加密规则

第一种

# AES加密              from Crypto.Cipher import AES              import base64              """              长度              16: *AES-128*              24: *AES-192*              32: *AES-256*              MODE 加密模式.常见的               ECB可以没有iv              CBC 需要iv的              """              # 创建加密器 注意秘钥和iv必须是16个字节              aes = AES.new( key= b"alexissbalexissb", mode=AES.MODE_CBC, iv=b"0102030405060708") # 分别是秘钥,模式,iv              data = "我吃饭了"              # 加密的内容必须是字节,所以先进行编码              data_bs = data.encode("utf-8")              # 需要加密的数据必须是16的倍数              # 填充规则: 缺少数据量的个数 * chr(缺少数据量个数)              pad_len = 16 - len(data_bs) % 16              data_bs += (pad_len * chr(pad_len)).encode("utf-8")              # 再对编码后的字节进行加密              bs = aes.encrypt(data_bs)              #用base64对结果进行编码              result = base64.b64encode(bs).decode()              

第二种,用pad对字节进行填充达到规定的长度

# AES加密              from Crypto.Cipher import AES              import base64              from Crypto.Util.Padding import pad              """              长度              16: *AES-128*              24: *AES-192*              32: *AES-256*              MODE 加密模式.常见的               ECB可以没有iv              CBC 需要iv的              """              # 创建加密器 注意秘钥和iv必须是16个字节              aes = AES.new( key= b"alexissbalexissb", mode=AES.MODE_CBC, iv=b"0102030405060708") # 分别是秘钥,模式,iv              data = "我吃饭了"              # 加密的内容必须是字节,所以先进行编码              data_bs = data.encode("utf-8")              # 需要加密的数据必须是16的倍数              # 用pad工具进行填充              data_bs = pad(data_bs,16)              # 再对编码后的字节进行加密              bs = aes.encrypt(data_bs)              #用base64对结果进行编码              result = base64.b64encode(bs).decode()              print(result)              

2, 加密结果转换base64,hex

# 转换成base64 bs是AES加密得到的字节              result = base64.b64encode(bs).decode()              #转换成16进制              import binascii              res = binascii.b2a_hex(bs).decode()              # 也可以转换成16进制,跟上面一个效果一样              bs.hex()              

3,解密规则

from Crypto.Util.Padding import pad,unpad              # base64编码后的密文              s = '9noPO0fcQizMbPkXcVOTDg=='              # 创建解密器              aes = AES.new(key= b"alexissbalexissb", mode=AES.MODE_CBC, iv=b"0102030405060708")              # 首先把base64编码转换成正常的字节              data = base64.b64decode(s)              res = aes.decrypt(data)              # 明文有可能有问题,因为字节是填充过得              # 用unpad 去除填充的内容,注:需要导入unpad              res = unpad(res,16)              # 得到明文              mingwen = res.decode("utf-8")              print(mingwen)              

9,DES加密

1,加密规则

from Crypto.Cipher import DES              from Crypto.Util.Padding import pad,unpad              import base64              mingwen = '艾尼在学爬虫'              # DES key 是 8个字节              # iv 在CBC 模式下使用 长度8个字节              des = DES.new(key=b'aininora', mode=DES.MODE_CBC,iv=b'ainiaini')              # 明文进行编码              data = mingwen.encode('utf-8')              # 对编码后的字节进行填充              r = pad(data,8)              # 对填充后的字节进行des加密后的字节              res = des.encrypt(r)              # 对加密后的字节进行base64编码              base64_res = base64.b64encode(res).decode()              print(base64_res)              

2,DES解密规则

from Crypto.Cipher import DES              from Crypto.Util.Padding import pad,unpad              import base64              #base64密文              miwen = 't4TYyzRnIkmVmI81n+cdsVQfprHN5AtG'              #转换成base64字节              base64_byt = base64.b64decode(miwen)              # 创建解密器对象              des = DES.new(key=b'aininora', mode=DES.MODE_CBC,iv=b'ainiaini')              # 进行解密              r = des.decrypt(base64_byt)              # 得到的结果去掉填充部分              data = unpad(r,8)              # 对得到的字节进行解码              mingwen = data.decode('utf-8')              print(mingwen)              

注:DES3 与AES,DES加密,解密规则一样,都是兄弟

注:js里的秘钥可以超过8位,js默认去前八位进行解密

10,RSA加密

1,RSA生成秘钥和公钥

#生成和处理秘钥的              from Crypto.PublicKey import RSA              # 加密和解密              from Crypto.Cipher import PKCS1_v1_5              import base64              # 生成私钥              #bits = 2048 是秘钥的长度              rsa_key = RSA.generate(bits=2048)              # 把秘钥导出来              # 秘钥的本质是字节              # export_key 有个参数叫format,默认为PEM,背后的含义是把秘钥转换成了base64              key = rsa_key.export_key().decode()              with open('./rsa_miyao.pem',mode='w',encoding='utf-8') as f:              f.write(key)              # 把format换成DER,拿到的是字节              # key = rsa_key.export_key(format='DER')              # 把字节手动转换成base64              # result = base64.b64encode(key).decode()              #生成公钥              public_key = rsa_key.public_key()              # 把公钥导出来              p_key = public_key.export_key()              with open('./rsa_gongyao.pem',mode='wb') as f:              f.write(p_key)              

2, RSA进行加密

#加密解密              from Crypto.Cipher import PKCS1_v1_5              #加载key              from Crypto.PublicKey import RSA              import base64              # 导入的key可以是PEM格式的秘钥,或者是直接形式的秘钥也可以              # 读取秘钥              f = open('./rsa_gongyao.pem',mode='r',encoding='utf-8')              # 拿到已经生成好的秘钥              pub_key = f.read()              f.close()              mingwen = "我要好好学习爬虫"              rsa_key = RSA.importKey(pub_key)              # 生成加密对象              rsa = PKCS1_v1_5.new(key=rsa_key)              # 对明文进行编码,处理成字节              mingwen_bs = mingwen.encode('utf-8')              # 对明文字节进行加密,得到密文字节              mi_bs = rsa.encrypt(mingwen_bs)              # 转换成base64              base_64 = base64.b64encode(mi_bs).decode()              #rsa每次加密后的结果可能不一样              print(base_64)              # 如果用了没有填充的算法,那每一次算出来的结果固定的              # 如果同一个明文反复计算结果是一样的那么考虑用js来完成逆向工作              

2.1 第二中加密方法

// JSEncrypt              // setPublicKey              // 用的是固定的第三方库,库的名字叫jsencrypt              // 但是这个库只能在浏览器环境使用              // 我们用的是Node环境,所以不能直接是哟和              // 我们需要换一个库, 名字叫 node-jsencrypt              // 安装 npm install node-jsencrypt              var {JSEncrypto} = require('node-jsencrypt')              var o = new JSEncrypto.setPublicKey('xxxxxxxxxxxxxxxxxxxxxxxx')              r = o.encrypt("加密的内容")              // 可以直接把网站的内容拿过来              

3,RSA特殊解密

3.1 第一特征

1,如果用了没有填充的算法,那每一次算出来的结果固定的

2,如果同一个明文反复计算结果是一样的那么考虑用js来完成逆向工作

// 特征:              // "010001" -> 这是16进制 -> 65537              // setMaxDigits              // RSAKeyPair              // encryptedString              const {              setMaxDigits,              RSAKeyPair,              encryptedString              } = require("./Ras加密");              function c(a,b,c){              var d,e;              return setMaxDigits(131),              d = new RSAKeyPair(b,"",c),              e = encryptedString(d,a)              }              

3,用RSA.js文件解决问题

例如:网易云案例

const CryptoJS = require("crypto-js")              var window = this              const {              setMaxDigits,              RSAKeyPair,              encryptedString              } = require("./Ras加密");              !function() {              function a(a) {              var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";              for (d = 0; a > d; d += 1)              e = Math.random() * b.length,              e = Math.floor(e),              c += b.charAt(e);              return c              }              function b(a, b) {              var c = CryptoJS.enc.Utf8.parse(b)              , d = CryptoJS.enc.Utf8.parse("0102030405060708")              , e = CryptoJS.enc.Utf8.parse(a)              , f = CryptoJS.AES.encrypt(e, c, {              iv: d,              mode: CryptoJS.mode.CBC              });              return f.toString()              }              function c(a, b, c) {              var d, e;              return setMaxDigits(131),              d = new RSAKeyPair(b,"",c),              e = encryptedString(d, a)              }              function d(d, e, f, g) {              var h = {}              , i = a(16);              return h.encText = b(d, g),              h.encText = b(h.encText, i),              h.encSecKey = c(i, e, f),              h              }              function e(a, b, d, e) {              var f = {};              return f.encText = c(a + e, b, d),              f              }              window.asrsea = d,              window.ecnonasr = e              }();              var params = {              csrf_token: "",              encodeType: "aac",              ids: "[1325905146]",              level: "standard"              }              var second = '010001'              var third = '00e0b509f6259df8642dbc35662901477df22677ec152b5ff68ace615bb7b725152b3ab17a876aea8a5aa76d2e417629ec4ee341f56135fccf695280104e0312ecbda92557c93870114af6c9d05c4f7f0c3685b7a46bee255932575cce10b424d813cfe4875d3e82047b97ddef52741d546b8e289dc6935b3ece0462db0a22b8e7'              var forth = '0CoJUm6Qyw8W8jud'              function fn(params) {              return window.asrsea(JSON.stringify(params),second,third,forth)              

4, RSA普通解密

#加密解密              from Crypto.Cipher import PKCS1_v1_5              #加载key              from Crypto.PublicKey import RSA              import base64              f = open('./rsa_miyao.pem',mode='r',encoding='utf-8')              # 拿到已经生成好的秘钥              pri_key = f.read()              f.close()              # 拿到秘钥              rsakey = RSA.importKey(pri_key)              # 生成解密器对象              rsa = PKCS1_v1_5.new(key=rsakey)              miwen = 'mmf28CJEtFU2Y6C/qx10xoaRmsiY2at3LBjHR5DFdnG9V+5sGPFaMGDGM4OBVWKKJNuSFZgGL9Y409mbh32IKRL4TZYnc0RvJH/0t38d7AmnqnHAyTRUvpKlPzzJg559md6BcTA/ZpYZ4WAtXRuysMvuPTdlRvog2ceGJDXURajU3KyzHXFA9Hc+AamVL75D+YKrOB6n9YeV7n4+DK5mqouNlLp6Plee39vYBzN0IKkzyD6RatmVVUIxJCsUJmeJgIdnBGEuRA9bGNOG3VQa7NF/syWjiRNbKYz+KZHx+RtQ9GuzmPhtJbjh8anPeR2kzNwgfD1HiKhIBDQKVQH/eA=='              #对密文进行base64解码转换成字节              base64_2bs = base64.b64decode(miwen)              #对拿到的字节进行rsa解密得到明文字节              # 解密第二个参数给个None,意思是解密时出错了返回None              mingwen_bs = rsa.decrypt(base64_2bs,None)              #对明文字节进行解码得到明文              mingwen = mingwen_bs.decode('utf-8')              print(mingwen)              

原文始发于微信公众号(安全君呀):逆向加密模块总结

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年12月16日10:27:01
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   逆向加密模块总结https://cn-sec.com/archives/3512523.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息