Python_編碼與加密

編碼與加密

  • 編碼、消息摘要算法和加密算法

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實現對代碼的分析和對語法樹的修改,並輸出混淆結果
    在這裏插入圖片描述

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>Title</title>
</head>
<body>
    <p>hello,today</p>
    <script type="text/javascript">
        document.oncontextmenu = function(){
            //禁用鼠標右鍵
            event.returnValue = false
        }
    </script>
</body>
</html>
  • 禁止複製和禁止選擇
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>hello,today</p>
    <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>Title</title>
</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,達到干擾爬蟲工程師調試代碼的目的
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章