Python_常见编码加密混淆

目录

      • 编码与加密与混淆
        • 1、编码
          • (1)ASCII编码
          • (2)Base64编码
        • 2、基于编码的反爬虫设计
          • (1)Base64编码反爬
          • (2)MD5反爬
          • (3)对称加密与AES
          • (4)非对称加密与RSA
        • 3、JavaScript代码混淆
          • (1)正则替换之变量名替换
          • (2)正则替换之进制替换
          • (3)代码编码之Base64
          • (4)代码编码之AAEncode
          • (5)代码编码之JJEncode
          • (6)代码复杂化之访问符
          • (7)代码复杂化之Packer
        • 4、混淆代码的还原
        • 5、混淆原理
        • 6、前端禁止事件
          • (1)禁止鼠标事件
          • (2)禁止键盘事件
          • (3)其他debug时,使用while 1启动无限debug,达到干扰爬虫工程师调试代码的目的

编码与加密与混淆

  • 编码、消息摘要算法和加密算法
1、编码
(1)ASCII编码
  • ASCII码默认使用7位二进制数来表示所有大写字母、小写字母、数字(0~9)、标点符号和特殊的控制符
(2)Base64编码
  • Base64基于64个可打印字符来表示8位二进制数据,用于解决不可打印的字符(如非英文的字符)在网络传输过程中造成的乱码现象
2、基于编码的反爬虫设计
(1)Base64编码反爬
  • Base64编码时所用的对照表是固定的,也就是说它的编码过程是可逆的。这意味着我们只需要将编码的流程倒置,就能得到解码的方法
  • 一般带有“==”符号或者“=”符号的字符串时,可能就是Base64编码字符串后得到的结果,按照Base64解码规则进行倒推,得到原字符
from base64 import b64decode

code = ["d3d3Lmh1YXdlaS5jb20=", "d3d3Lmp1ZWppbi5pbQ=="]
for c in code:
    s = b64decode(c).decode("utf8")
    print(s)
# www.huawei.com
# www.juejin.im
  • 难点:Base64编码和解码时都是将原本8位的二进制数转换成6位的二进制数。如果我们改动位数,将其设置为5位或者4位,那么就可以实现新的编码规则,这时如果还是使用原先的方法进行解码,就可能解码不成功。改动位数,将其设置为5位或者4位
(2)MD5反爬
  • MD5是一种广泛使用的散列函数,它能够将任意长度的消息转换成128位的消息摘要。与Base64编码不同的是,MD5是不可逆的,这意味着我们可以将字符串转换为MD5值,但无法将MD5值换成MD5值转换成原字符串。
  • 相比Base64编码,MD5运算过程要复杂很多。由于MD5在运算过程中使用了补位、追加和移位等操作,所以他人无法从输出结果倒推出输入字符,这个特性被称为“不可逆”。
  • MD5可以对任意长度的消息进行运算,输出固定位数(128位)的结果,这个特性被称为“压缩”
(3)对称加密与AES
  • 加密和解密时使用同一个密钥的加密方式叫做对称加密,使用不同密钥的是非对称加密
  • 对称加密
加密_密钥A -- --
解密_密钥A -- --
明文
密文
  • 非对称加密
加密_密钥A _公钥 -- --
解密_密钥B_私钥 -- --
明文
密文
  • 相对于非对称加密来说,对称加密的速度更快,速度的优势使得它更适合大量数据加密的场景,常见的堆成加密算法有DES、3DES、BLOWFISH、RC5和AES等
  • AES加密过程中的操作是可逆的,关键在于密钥
from Crypto.Cipher import AES
# 初始化AES对象时传入密钥,加密模式,和iv
aes1 = AES.new('63f09k56nv2b10cf', AES.MODE_CBC, "01pv928nv2i5ss68")
# 待加密消息
message = "Hi I am from the earth number 77"
print(f"待加密消息{message}")
# 加密操作
cipher_text = aes1.encrypt(message)

# 初始化AES对象时传入与加密时的相同的密钥、加密模式和iv
aes2 = AES.new('63f09k56nv2b10cf', AES.MODE_CBC, "01pv928nv2i5ss68")
plaint_text = aes2.decrypt(cipher_text)
print(f"密文{cipher_text}")
print(f"明文{plaint_text.decode('utf8')}")
(4)非对称加密与RSA
  • 在不传递密钥的情况下实现加密和解密操作,与对称加密不同的是,这种方式需要用到两个密钥:公钥和私钥。
  • 公钥和私钥是一对,如果用该公钥对数据进行加密,那么只有用对应的私钥才能够解密数据,反之亦然;用的最多的是RSA,可逆
from Crypto import Random
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
import base64


message = 'async'  # 消息原文

# 初始化乘积n长度为1024的RSA对象
rsa = RSA.generate(1024, Random.new().read)
# 生成私钥
private_key = rsa.exportKey()
# 生成公钥
public_key = rsa.publickey().exportKey()
# 打印私钥和公钥
print(private_key.decode('utf8'))
print(public_key.decode('utf8'))

# 将私钥和公钥存入对应名称的文件
with open('private.pem', 'wb') as f:
    f.write(private_key)

with open('public.pem', 'wb') as f:
    f.write(public_key)

with open('public.pem', 'r') as f:
    # 从文件中加载公钥
    pub = f.read()
    pubkey = RSA.importKey(pub)
    # 用公钥加密消息原文
    cipher = PKCS1_v1_5.new(pubkey)
    c = base64.b64encode(cipher.encrypt(message.encode('utf8'))).decode('utf8')

with open('private.pem', 'r') as f:
    # 从文件中加载私钥
    pri = f.read()
    prikey = RSA.importKey(pri)
    # 用私钥解密消息密文
    cipher = PKCS1_v1_5.new(prikey)
    m = cipher.decrypt(base64.b64decode(c), 'error').decode('utf8')

print(f'消息原文:{message}\n消息密文:{c}\n解密结果:{m}')
3、JavaScript代码混淆
  • 网页打开速度:即资源加载速度和页面渲染速度;
  • 代码压缩:资源加载速度的常用优化方法是压缩,压缩的对象包括HTML文档、图片和JavaScript文件等。压缩后的文件体积相对较小,不仅有利于网络传输,还能起到保护代码的作用。这是因为在压缩过程中会删除注释、空格和换行符等元素,将多个JavaScript文件合并以及缩短变量名。
  • 随着浏览器和各大IDE推出代码格式化功能,文件压缩对代码的保护就被削弱了;为了更好地保护代码,开发者想到了代码混淆这样的办法
  • 常见的混淆方法:正则替换、代码编码和代码复杂化等
(1)正则替换之变量名替换
  • 用简短的字母替换方法中的变量名,也可以在此基础上增加空格和换行符的删除操作,原代码如下
function transToDict(name, age, vip){
    /* 格式转换 */
    result = "{name:" + name + ", age:" + age + ", isVIP:" + vip + ",}";
    console.log(result);
    return result;
}
(2)正则替换之进制替换
  • 除了能解析Base64编码外,浏览器还能解析十六进制的字符。原代码如下
var ins = 1 + 2, ss = "abc";
function pack(a, b){
    return a + b + ss;
};
var pp = pack(ins, 6);
console.log(pp);
(3)代码编码之Base64
  • 浏览器会自动解析Base64编码后的内容,切换到Console可以看到输出结果
(4)代码编码之AAEncode
  • 代码混淆不仅是替换一些字符,一些奇怪的编码也能起到保护代码的作用。常见的编码方法有AAEncode和JJEncode。
  • AAEncode能将JavaScript代码转换为颜文字,而JJEncode则将代码转换为“$”符号、"_“符号和”+"符号。
(5)代码编码之JJEncode
  • JJEncode与AAEncode的编码原理相似,但输出的符号不同。
(6)代码复杂化之访问符
  • 有些混淆方法则是改变对象的访问符,如将原本用",“访问对象的方式改为用”[]"访问,在此基础上,加入十六进制和Unicode混淆手段
(7)代码复杂化之Packer
  • Packer是代码混淆中常用的方法,它能将原代码变得复杂,降低可读性
4、混淆代码的还原
  • 混淆并不是加密,混淆后的代码肯定能够在浏览器中执行,否则混淆就失去了意义。所以说,混淆的代码可以被还原,只不过不同的混淆手段在还原时耗费的时间不同,
  • 代码还原有一定的规律,例如正则替换这种混淆方法通常会将数字和字母转换为十六进制
  • 在调用Base64编码后得到的代码时,需要使用eval关键字
eval(atob("basefahuh=="))
  • AAEncode 和JJEncode的编码结果可以直接运行,不需要再代码前加eval。这两种编码的还原方式很简单,只需要用到console shell工具,需要删除最后一组括号内的信息
  • Packer的还原和Base64一样,需要使用eval关键字,只需要用到console shell工具即可看到原代码
5、混淆原理
  • 混淆功能的关键是:抽象语法树(abstract syntax tree,简称AST)
  • JavaScript编译器的目的是将JavaScript代码编译为机器码,而混淆的处理结果仍然是JavaScript代码
  • 混淆器在代码编译过程中修改语法树,并将输出结果改为JavaScript,了解混淆器对代码的处理流程后,就可以动手编写混淆器了
  • 可以借助UglifyJS实现对代码的分析和对语法树的修改,并输出混淆结果
    Python_常见编码加密混淆_第1张图片
6、前端禁止事件
  • 当事件触发时,会执行对应的JavaScript
(1)禁止鼠标事件
属性 描述
onclick 当用户点击某个对象时调用的事件句柄
oncontextmenu 在用户点击鼠标右键打开上下文菜单时触发
ondbclick 当用户双击某个对象时调用的事件与句柄
onmousedown 鼠标按钮按下
onmouseenter 当鼠标指针移动到元素时触发
onmousemove 鼠标被移动
onmouseover 鼠标移到某元素之上
onmouseout 鼠标从某元素移开
onmouseup 鼠标按键被松开
  • 开发者可以通过JavaScript在HTML中注册oncontextmenu事件检测鼠标右键,当检测到鼠标右键被按下时重置事件或返回false,这样就能够实现鼠标右键的检测和禁用,进而限制开发者工具的唤起操作;但是ctr+shift+I可以
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <p>hello,todayp>
    <script type="text/javascript">
        document.oncontextmenu = function(){
            //禁用鼠标右键
            event.returnValue = false
        }
    script>
body>
html>
  • 禁止复制和禁止选择
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <p>hello,todayp>
    <script type="text/javascript">
        document.oncopy = function(){
            //禁用复制可导致复制无效
            event.returnValue = false
        }
    script>
body>
html>
(2)禁止键盘事件
  • 常见的键盘事件、值和对应描述
事件 描述
VK_F5 0x74(116) F5键
VK_F12 0x7B(123) F12键
VK_DELETE 0x2E(46) Delete键
VK_PAGE_UP 0x21(33) Page up键
VK_PAGE_DOWN 0x22(34) Page down键
  • F12键限制
DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>
head>
<body>
    <p>用户无法通过F12键唤起开发者工具p>
    <script type="text/javascript">
        document.onkeydown = function(){
            if (window.event  && window.event.keyCode == 123){
                event.returnValue=false
            }
            event.returnValue = false
        }
    script>
body>
html>
(3)其他debug时,使用while 1启动无限debug,达到干扰爬虫工程师调试代码的目的

你可能感兴趣的:(#,SpiderCrawl,python,爬虫)