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

此文原由

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

登陸抓包

閒話少說,既然是模擬登陸,咱們來看看登陸過程都發生了什麼。html

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

先看返回頭:git

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

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,後果你懂的。ajax

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

再看請求頭:瀏覽器

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

最後看 post 的數據:cookie

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

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,歡迎交流探討。

相關文章
相關標籤/搜索