博客園的模擬登錄實現以及加密方式淺析


此文起因

有園友私信我探討關於博客園模擬登錄的事,年前也玩了一段時間的 node(詳情可以參考我的 node 項目集 https://github.com/hanzichi/funny-node 厚着臉皮求 star),做之前想的可能只是一次簡單的 post,嘗試下來完成后還是有了不少收獲。為了能讓后人有個參考,遂成此文。

登錄抓包

閑話少說,既然是模擬登錄,我們來看看登錄過程都發生了什么。

打開登錄頁面(http://passport.cnblogs.com/user/signin?ReturnUrl=http://passport.cnblogs.com/),填入用戶名和密碼,點擊登錄后,我們很容易地抓到了登錄包。

先看返回頭:

后續的實踐中,我用回帖操作來證明已經完成登錄。抓取回帖的包,發現回帖操作需要攜帶一個 key 為 .CNBlogsCookie 的 cookie 識別身份。又發現,只要一次登錄后將瀏覽器中的該 cookie 取出,就能模擬該用戶了。我將客戶端的 key 為 .CNBlogsCookie 的 cookie 取出,寫下如下代碼:

superagent
  .post('http://www.cnblogs.com/mvc/PostComment/Add.aspx')
  .set("Cookie", ".CNBlogsCookie=yourCookieValue")
  .send({"blogApp": "xxx"})
  .send({"body": "test"})
  .send({"postId": xxx})
  .end(function (err, sres) { // callback
  });

居然能回帖,完全不用管其他操作了。不明原因,但是細思極恐,如果你被人盜取了該 cookie,后果你懂的。

要手動從瀏覽器中復制獲取該 cookie 顯得有點 low,如何能自動獲取該 cookie 值?

再看請求頭:

實踐發現,有四個值是必須模擬的(已標出),而且全都照抄即可。

最后看 post 的數據:

這是什么玩意?原來是加密后的用戶名以及密碼數據。接下去簡單了解下加密方式(盡管模擬登錄並不強依賴於此)。

jsencrypt

博客園的加密方式為 RSA,依賴 jsencrypt 這個庫。

這里不詳述 RSA 加密方式,詳情可以參考阮一峰老師的文章:

jsencrypt 加密是可逆的加密方式,客戶端用公鑰加密,服務端用私鑰解密,每次加密生成的字符串都不一樣,但是解密后都一樣。用明文發送賬戶名和密碼,如果該包被截獲,那么你的密碼也將大白於天下,存在着極大的安全隱患,但是客戶端用了 jsencrypt 加密,如果被截獲,截獲的也僅僅只是加密后的字符串,沒有私鑰解密的話,也無濟於事。我們 post 包中的 input1 和 input2 的數據正是在客戶端加密后的用戶名以及密碼。

打開 http://passport.cnblogs.com/user/signin?ReturnUrl=http://passport.cnblogs.com,ctrl+u 查看網頁源代碼,可以清楚看到 jsencrypt 加密的公鑰,賬戶名密碼的加密過程,以及用 ajax 方式登錄所需要的數據等。

參考 博客園加密登錄--jsencrypt 我寫了個簡單的基於 jsencrypt 的加密解密 demo https://github.com/hanzichi/funny-node/tree/master/cnblogs-auto-login/jsencrypt-demo。因為解密過程有用到 PHP 中的 openssl,所以記得在 php.ini 文件中打開 openssl,具體操作為找到 extension=php_openssl.dll 這一行,把注釋打開(將前面的封號去掉)。

另外,根據已經披露的文獻,目前被破解的最長 RSA 密鑰是 768 個二進制位。也就是說,長度超過 768 位的密鑰,還無法破解(至少沒人公開宣布)。因此可以認為,1024 位的 RSA 密鑰基本安全,2048 位的密鑰極其安全。Online RSA Key Generator 可以參考 http://travistidwell.com/jsencrypt/demo/index.html,我這也備份了一份 https://github.com/hanzichi/funny-node/tree/master/cnblogs-auto-login/key-generator

編碼

進入最后編碼階段。

首先我們需要獲取加密后的賬戶名以及密碼,可以抓個包復制下參數,雖然每次加密后的字符串都不一樣,但是解密后的結果是一樣的,所以如果后期不主動修改用戶名和密碼,這樣做完全沒有問題。但是我覺得這樣做不優雅,能不能通過用戶名和密碼,獲取加密后的結果?嘗試着找了下 node 下的 RSA 模塊,無奈可能使用方式不大一樣,未果。於是換了個方式,客戶端進行加密,將加密后的數據存儲到服務端,供 node 調用。

然后就是模擬登錄了,VerificationToken 參數可以爬取頁面取,也可以直接拿個值賦值。登錄成功后保存 cookie 以便下次操作時調用。

詳細代碼和操作步驟已同步在 Github,歡迎交流探討。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM