很多人都會問這樣一個問題,我們在登錄的時候,密碼會不會泄露?隨便進一個網站,登錄時抓包分析,可以看到自己的密碼都是明文傳輸的,在如此復雜的web環境下,我們沒有百分的把握保證信息在傳輸過程中不被截獲,那不使用明文如何告訴服務器自己的身份呢?
在一些高度通信安全的網絡中,數據傳輸會使用HTTPS作為傳輸協議,但是通常情況下我們沒必要使用HTTPS傳輸,雖說安全,但傳輸數據都需要加密解密,很費時。我們可以使用一些加密方式(如md5)對密碼進行加密,如果僅僅只對密碼加密那肯定是沒有任何作用,所以可以在密碼中加入一些其他的字符,合並之后使這個密碼成為一個臨時密碼~
<label>username:</label><input id="uid" type="text" /> <label>password:</label><input id="pwd" type="password" /> <input type="submit" /> <script type="text/javascript"> var t = new Date*1, uid = $("#uid").val(), pwd = $("#pwd").val(), delta = encrypt($("#pwd").val() + t); $.post("./login.php",{ uid: $("#uid").val(), pwd: delta, tid: t }, function(data){ //do something. }) </script>
在上面,提交表單的時候,pwd並不是真實的密碼,他是pwd與t混合再加密的字符串。這樣的字符串即便是被人截獲也是一個無效的數據,即便是截獲並知道了破解方式,我們還可以在后台給他設定一個時效限制。
<?php define("uid", "user-A"); define("pwd", "user-A-pwd"); if(time() - $_POST['tid'] > 60*2 || $_POST['uid'] !== uid || decrypt(pwd . $_POST['tid']) !== $_POST['pwd']){ die("error"); } ?>
如果下面三個條件有一個不滿足就報錯
- 時間超過2分鍾
- uid不匹配
- pwd與t的組合密碼不匹配
當然,上面提到的encrypt和decrypt都是約定好的加密和解密方式,通常會使用md5加密。
這樣的加密傳輸方式,需要客戶端和服務器端的時間比較准確。如果要考慮時間不准確問題以及hacker動作迅速的問題,那就得用token來驗證了。
所謂的token,其實就是在登錄之前向服務器發送一個請求,獲取准入的一個臨時密碼,這個臨時密碼是由服務器給出,所以不存在上面所說的時間不准確問題,同時這個token也是一個隨機的字符串,只能單次使用,hacker很難獲取,即便獲取也無法使用,因為下一步登錄所需的信息他沒有。
很多童鞋都用過人人、QQ、微博的開發平台,其中OAuth認證也就是這個原理。就拿人人開發平台的認證來說,他的認證流程是這樣的:
通過你在平台申請的API KEY向https://graph.renren.com/oauth/authorize請求一個臨時密碼,也就是token code,然后利用token code向https://graph.renren.com/oauth/token請求用戶數據。整個流程十分簡單。
這是一個簡單的demo,獲取你的頭像和姓名。人人OAuth認證demo
使用token的弊端是需要額外發送一次請求,過程稍微復雜。有些公司VPN通道就是利用token做密碼,為了保證高安全性,他們使用的是一個信息與服務器同步硬件設備,和銀行發的動態口令一樣,每次登陸都需要輸入這個口令,那這個口令也就是token,不過他不是網絡傳輸獲取,所以安全性更高。