大家好,又見面了,我是你們的朋友全棧君。
目前加密的方式總結有下面幾點:
- 對稱加密(加密解密密鑰相同):DES、DES3、AES
- 非對稱加密(分公鑰私鑰):RSA
- 信息摘要算法/簽名算法:MD5、HMAC、SHA
- 前端實際使用中MD5、AES、RSA,自定義加密函數使用頻率是最高的
- 幾種加密方式配合次序:采用非對稱加密算法管理對稱算法的密鑰,然后用對稱加密算法加密數據,用簽名算法生成非對稱加密的摘要
- DES、DES3、AES、RSA、MD5、SHA、HMAC傳入的消息或者密鑰都是bytes數據類型,不是bytes數據類型的需要先轉換;密鑰一般是8的倍數
- Python實現RSA中,在rsa庫中帶有生成簽名和校對簽名的方法
- 安全性:DES<DES3=AES<RSA,至于MD5、SHA、HMAC不好說了
搜其他關鍵詞如RSA、encrypt,尤其是encrypt
其中this.exponent是RSA加密偏移量 ,數值一般在HTML文件里面,全局搜索,其value值就是
密鑰的值一般在網頁源碼的一個元素值。全局搜索,其value值就是,或者是js中找到
AES:案例ewt360.com
AES是典型的對稱加密,密鑰就在前端源碼里,相對于非對稱的RSA安全性很低
var com_str = { _KEY: "20171109124536982017110912453698",//32位
_IV: "2017110912453698",//16位 *str:需要加密的字符串
Encrypt: function (str) { var key = CryptoJS.enc.Utf8.parse(this._KEY);
var iv = CryptoJS.enc.Utf8.parse(this._IV); var encrypted = '';
var srcs = CryptoJS.enc.Utf8.parse(str);
encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv,
mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
return encrypted.ciphertext.toString(); }, }
此處還調用了CryptoJS,它是加密的核心類,但發現沒有,其實是藏在另外一個js文件中,找到并復制出來,將兩個js合并即可
自定義加密:空中網
這個網站是以get方式登陸的,由一個eval加密的js
function encrypt () this.encrypt(pwd, this.j_data["dc"])
加密原理:在打開網站的時候服務器會返回一串字符串,用于加密,加密的js是通過eval方式處理的
js混淆:就是把其中的變量、方法位置順序打亂,但是又用一些無關的變量或者方法來保證執行順序
解決方法:復制完整的混淆代碼去js混淆還原網站還原。
注意:很多時候,js代碼的生成函數都進行了偽裝,核心的東西只有一句,但有一堆混淆視聽的js,只需要找到核心代碼,進行解析就行
eval加密:
eval()方法:js中的eval()方法就是一個js語言的執行器,它能把其中的參數按照JavaScript語法進行解析并執行,簡單來說就是把原本的js代碼變成了eval的參數,變成參數后代碼就成了字符串,其中的一些字符就會被按照特定格式“編碼” 。
例如下:
eval(function(p,a,c,k,e,d){e=function(c) {return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?
String.fromCharCode(c+29):c.toString(36))}; if(!''.replace(/^/,String)){while(c--)d[e(c)]=k[c]||e(c);
k=[function(e){return d[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace
(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('5 4="粘貼要加密/解密的3代碼到這里";
2(0==0){ 1(4);}',62,6,'1|alert|if|javascript|showmsg|var'.split('|'),0,{}))
解決方法:將代碼字符串放入javascript Eval官網解密
再看eval解密后的js文件尾部,有下面一個函數
function encryptString(str, e, m) {
var key = RSAUtils.getKeyPair(e, '', m);
return RSAUtils.encryptedString(key, str) }
發現是RSA加密方式,那現在從RSA加密逆向搜索encryptString關鍵詞 ,找到下面
var timesign = (new Date).getTime() + timespan;
$("#p1User").val(encryptString(timesign + encodeURIComponent($("#passwordUser").val()),
$("#rsaExponent").val(), $("#rsaModulus").val()));
$("#password_value").val($("#passwordUser").val());
$("#btnSubmitUser").val("登錄中...");
$("#usernameUser").addClass("fontcolor_cccUser").attr("readonly", "readonly");
$("#passwordUser").val("").addClass("fontcolor_cccUser").attr("readonly", "readonly");
篩選核心代碼
encryptString(timesign + encodeURIComponen ($("#passwordUser").val()),
$("#rsaExponent").val(), $("#rsaModulus").val());
(“#passwordUser”).val(),rsaExponent”).val(), $(“#rsaModulus”).val()
這三個參數分別是從頁面獲取id,去html搜索這三個關鍵詞
rsaExponent 看到value為01001,故此RSA加密偏移量為01001
rsaModulus 也是看到value為一群亂碼,它是RSA密鑰
用戶認證的話會涉及到cookie
解決方法:查看cookie數據,找到經過例如:fingerprint進行URL解碼,對比請求參數fingerprint修改
那么,逆向解密解決思路呢?
逆向解密解決思路:
(1)是根據加密參數,如“x-uab”關鍵字在所有關鍵中查找
- 打開chrome瀏覽器 按F12
- 找到點擊source中 按ctrl + shift + F快捷鍵 ,輸入x-uab找到js代碼
- 接下來,打個斷點調試一下:在數字那里點一下,數字位置出現藍點,表示添加斷點成功
- 然后刷新獲取店鋪列表的頁面,程序會在斷點處停下,在控制臺調試o.getUA()函數,看一下輸出
- 繼續向下查看這個關鍵詞參數 js 生成函數的引用,一步步往回推,找到最原始的 js 生成方法
- 找到以后,把這個function 方法全部代碼取出來,另存為一個js文件。
(2)怎么用python執行js腳本?
方法一:
自己搞懂生成的過程,是md5還是AES加密,找到key值,時間戳其余參數啥的也可以生成,做過后臺開發的會比較清楚其生成原理,因為需要對接前后端接口
方法二:execjs
因為在上面復制出來的腳本中,只單單定義了一個方法,并沒有調用這個方法,所以,要在js文件的末尾添加一些代碼來調用
function getParam() { var a; var param = e(2,a); return param };
然后,開始擼Python代碼吧
原理:將execjs的引擎換成PhantomJS這個無頭瀏覽器,換句話說就是用PhantomJS來執行js腳本,PhantomJS是一個瀏覽器,自然就會創建window對象。
import execjs import os os.environ["EXECJS_RUNTIME"] = "PhantomJS"
node = execjs.get() file = 'eleme.js' ctx = node.compile(open(file).read())
js_encode = 'getParam()' params = ctx.eval(js_encode) print(params)
不用PhantomJS方法
import execjs node = execjs.get() file = 'eleme.js' ctx = node.compile(open(file).read())
js_encode = 'getParam()' params = ctx.eval(js_encode) print(params) 可能會
報錯:execjs._exceptions.ProgramError: TypeError: 'window' 未定義 原因:window對象
估計是瀏覽器打開是創建的,蘊含瀏覽器的信息,所以用Python來執行這段代碼時,沒有這個對象
方法三:
思路和方案二類似,不過更加粗暴一些。因為沒在瀏覽器執行,那就模擬瀏覽器來執行。
在執行之前,同樣要修改js腳本,在js文件末尾調用e方法,添加如下代碼,例:
var a; var param = e(2,a); return param;
注意:調用方法不要放在任何函數里面,我之前就是因為將這段代碼放在函數里頭強制執行,導致的結果就是在瀏覽器里可以獲取加密字符串,但是在Python中獲取到的卻是None
模擬瀏覽器用的selenium和chrome的webDriver,代碼如下:
from selenium import webdriver
browser = webdriver.Chrome(executable_path='chromedriver.exe')
with open('eleme.js', 'r') as f: js = f.read() print(browser.execute_script(js))
最終獲得加密之后的字符串
最后,有必要說一下,如果需要獲取大量的x-uab,采用方案三效率會高一下,因為采用方案二的話,可以自打開一個瀏覽器(都調用一個webdriver對象),然后快速執行js,返回加密字符串。
|