## 1 有隱患登錄的驗證方式?
### 1.1有隱患登錄的驗證方式介紹
? ? ?
? ? 如圖所示,從firebug上抓取到我們輸入完用戶名和密碼之后的信息,url:http://xxx.com/doLogin.php?username=CleverCode&pwd=123456,可以看出,我們的請求方式是Get請求,還有我們現在的密碼傳輸用的是明文傳輸。可以很清楚的看到我們登錄時候傳遞的URL中附帶上了用戶名:CleverCode,密碼是:123456。
### 1.2存在的問題
? ? 1) GET請求:
? ? ? ? 可以看到,在傳輸用戶名和密碼的時候是用的GET請求方式。這種請求方式參數會附帶在URL中。這樣會帶來潛在的安全隱患。建議使用POST請求。
? ? 2)傳輸的過程中密碼是明文:
? ? ? ? 在傳輸的過程中,發現傳輸的密碼是明文,這個很容易就把用戶的密碼給泄露了。建議將密碼加密后在進行傳輸。
### 1.3潛在的風險
? ? 在傳輸的過程中使用了GET請求,并且密碼沒有進行加密。每次瀏覽器進行請求的時候,有的瀏覽器設計公司會記錄下每次請求的URL,然后在進行一些行為分析,如果是這樣,那么我們的用戶的密碼將存在非常的大的隱患。很有可能別人竊取。從而進行一些對本公司不利的活動。
## 2建議改進的登錄驗證方式
### 2.1 設計方案介紹
? ? 在設計的過程中,可以使用POST請求,POST請求,在傳輸過程中參數不會被附加在URL上,這個可以防止它人進行用戶行為分析的時候,分析出用戶名和密碼。在傳輸的過程中,可以將密碼進行加密,然后進行密文傳輸。密文加密的時候可以使用哈希函數中的md5()算法。Md5()加密的后的密文不會有哈希沖突,是常見的加密方式之一。
### 2.1.1 前臺頁面源代碼
~~~
<?php
//頁面加載時間
$loadtime = time();
?>
<script>
? ? //頁面js本機加載時間
? ? var loadtime = parseInt(new Date().getTime()/1000);
? ??
? ? // 登錄信息檢查
? ? function onlogin(){
? ? ? ? var personId = document.login_form.personId.value;
? ? ? ? var passwd = document.login_form.passwd.value;
? ? ? ? if (personId.length == 0 || passwd.length == 0){
? ? ? ? ? ? alert("無效的用戶名或口令");
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? var currtime = parseInt(new Date().getTime()/1000);
? ? ? ??
? ? ? ? //當前時間戳 = php的loadtime時間 + (js當前時間 - js的load時間)
? ? ? ? var timestamp = <?php echo $loadtime;?> + currtime - loadtime;
? ? ? ??
? ? ? ? //將123456進行md5加密
? ? ? ? var passwdMd5 = hex_md5(passwd);
? ? ? ??
? ? ? ? //將CleverCode與passwdMd5以及與當前時間加密
? ? ? ? passwdMd5 = hex_md5(personId + passwdMd5 + timestamp);
? ? ? ? document.login_form.timestamp.value = timestamp;
? ? ? ? document.login_form.passwdMd5.value = passwdMd5;
? ? ? ? // hide the password
? ? ? ? document.login_form.passwd.value = "******";
? ? ? ? return true;
? ? } ?
</script>
~~~
### 2.1.2 前臺頁面源代碼說明
? ? 1)傳給服務器的數據結構樣例:
? ? ? ? personId:CleverCode
? ? ? ? passwdMd5: 202cb962ac59075b964b07152d234b70
? ? ? ? timestamp:1393998153
? ? ? ? passwd:
? ??
? ? 2)計算當前時間戳:
? ? ? ? 首先使用php把當前服務器的時間戳賦值給了$loadtime,在js環境加載的時候,首先記錄的js的加載時間loadtime = parseInt(new Date().getTime()/1000),這個時間是客戶端的時間,在點擊完登錄按鈕之后,在記錄var currtime = parseInt(new Date().getTime()/1000)時間,當前的currtime是用js求得的,得到的客戶端瀏覽器所在機器的時間,每個人客戶端的時間設置可能都不一樣,使用var timestamp = <?php echo $loadtime;?> + currtime – loadtime,就可以得到現在真正的時間。我們只取了在客戶端登錄的時間差,然后加上服務器的起始時間,那么就可以到的當前時間。
? ??
? ? 3)密碼加密:
? ? ? ? 首先對用戶的密碼進行md5加密var passwdMd5 = hex_md5(passwd);,js中md5的加密函數為hex_md5();然后在用戶的Id與passwdMd5與時間戳一起md5加密passwdMd5 = hex_md5(personId + passwdMd5 + timestamp),得到真正要傳輸給服務器的md5密碼。
? ??
? ? 4)迷惑密碼:
? ? ? ? document.login_form.passwd.value = "******",這部分為使用的迷惑密碼,并沒有多大的實際意義。
### 2.2 后臺驗證設計
### 2.2.1后臺頁面源代碼
~~~
function checkLogin($personId, $timestamp, $passwdMd5){
//檢驗時間戳
$lifeTime = 60;
$nowTime = time();
//登錄頁面如果超過60s,則超時需要重新輸入
if(($nowTime - $timestamp) >= $lifeTime){
return 'Error:invalid timestamp!';
}
//檢驗用戶是否存在
if(isUers($personId) === false){
return "Error:$personId not exitsts!";
}
//獲取用戶的密碼,該密碼為用戶密碼明文的MD5值,保存在數據庫中
$passwd = getPasswd($personId);
//檢驗密碼是否正確
$realPasswd = md5($personId.$passwd.$timestamp);
if($realPasswd == $passwdMd5){
return 'OK'
}
return "Error:passwd not right!"
}
~~~
### 2.2.2后臺頁面源代碼說明
? ? 首先獲取服務器當前時間戳$nowTime,用當前的時間戳減去傳入的時間戳$timestamp,如果大于等于60s說明,響應時間超時,必須放棄這條檢測;然后判斷當前的用戶是否存在;接著從保存用戶密碼的地方獲取用戶的密碼$passwd,用戶在數據庫中保存的密碼必須是明文的md5值;然后$personId.$passwd.$timestamp進行md5加密得到真正的密碼$realPasswd;最后對傳入的密碼$passwdMd5與$realPasswd進行比較
### 2.3 設計方案的優點
? ? 1) 使用POST請求傳輸,避免了url在傳輸過程中被它人竊取用戶名和密碼。
? ? 2) 密碼傳輸的方式不再是明文傳輸,而是使用密文傳輸,不容易被破解。
? ? 3) 在傳輸的時候,首先對用戶密碼的明文進行md5計算,然后在對passwdMd5 =hex_md5(personId + passwdMd5 + timestamp)。為什么不直接將明文md5后就直接傳輸的原因是,如果有人有足夠強大的md5映射庫。然后他只需要拿到你的密文之后再進行匹配,即采用枚舉破解法,既可以知道了明文。使用的timestamp之后就很難暴力破解了。
? ? 4)加密過程中使用時間戳,增加了加密的復雜度,提高了安全性。
### 2.4 設計方案的不足
? ? 登錄的時候沒有設計驗證碼類似的功能,登錄的接口直接裸露出來,很容易被它人模擬http請求,大量請求這個接口,造成這個接口的崩潰。建議自行設計時候,當用戶如果輸入密碼錯誤N次的時候,需要輸入驗證碼。
**版權聲明:**
**1)**原創作品,出自"CleverCode的博客",轉載時請務必注明以下**原創****地址**,否則追究版權法律責任。
**2)**原創地址**:[http://blog.csdn.net/clevercode/article/details/45481409](http://blog.csdn.net/clevercode/article/details/45481409)(**轉載**務必注明該地址**)**。**
**3)**歡迎大家關注我博客更多的精彩內容:[http://blog.csdn.net/CleverCode](http://blog.csdn.net/CleverCode)。