HTTP協議下保證登入密碼不被獲取最健壯方式

2021-09-07 07:15:02 字數 3083 閱讀 6428

原文:

說到在http協議下使用者登入如何保證密碼安全這個問題:

小白可能第一想法就是,使用者在登入頁面輸入密碼進行登入時,前台頁面對使用者輸入的密碼進行加密,然後把加密後的密碼作為http請求引數通過網路發到伺服器。

這樣做是無法保證使用者的賬戶安全的,因為稍微懂一點程式設計知識的人就可以通過你傳送的http請求知道了你的密碼,小白又說了,我密碼加密了,它拿到的也是加密後的密碼,它不知道我的原始密碼它是無法從登入頁面登入的。

原文和作者一起討論:

但是小白啊,你有沒有想過,有時候我僅僅知道你加密後的明文就夠了,我可以自己偽造http請求,把明文加在請求引數裡面,一樣可以登入系統的。

大白這時候有話說了,大白:我可以對密碼進行加鹽。好,我們先看加鹽是什麼,加鹽簡單說就是程式對使用者設定的原始密碼後面追加隨機數來加強使用者密碼的複雜性,然後再對組合後的密碼進行加密進行儲存,使用者每一次登入,前端先對使用者輸入密碼進行加密傳輸到後端,然後後端獲得使用者賬號到資料庫找到該使用者的鹽,再和傳來的明文組合一起進行一次加密後與資料庫中的密碼進行對比來判斷是否是符合使用者。但是啊,大白,你看,這樣做,並無法控制其他人通過你http請求獲得明文,獲得後,人家照樣大搖大擺使用你的身份登入系統進行操作。

好,大白讓我跟你講講加鹽的真正意義:加鹽的意義不是為了保證密碼在網路傳輸的安全性,而是防止資料庫被人入侵後,由於原始密碼太過簡單,被人分析出來,進而知道了密碼。直接對密碼進行md5處理後,反向解密確實難度很大,但還是可以找出破綻的 例如:兩個人或多個人的密碼相同,通過md5加密後儲存會得到相同的結果。破乙個就可以破一片的密碼。如果使用者可以檢視資料庫,那麼他可以觀察到自己的密碼和別人的密碼加密後的結果都是一樣,那麼,別人用的和自己就是同乙個密碼,這樣,就可以利用別人的身份登入了。那麼我們以前的加密方法是否對這種行為失效了呢?其實只要稍微混淆一下就能防範住了,這在加密術語中稱為「加鹽」。具體來說就是在原有材料(使用者自定義密碼)中加入其它成分(一般是使用者自有且不變的因素),以此來增加系統複雜度。當這種鹽和使用者密碼相結合後,再通過摘要處理,就能得到隱蔽性更強的摘要值。

小黑說:你說的這些我都懂,我來告訴你最終的方案吧:在使用者輸入完賬號後,後台ajax傳送使用者的賬號到伺服器,這個時候伺服器為該賬號生成乙個隨機數驗證碼,響應給前端登入頁面。

當使用者輸入密碼後,前端頁面對使用者輸入的密碼進行加密,然後把加密後的明文和獲得伺服器返回的驗證碼組合在一起再一次進行加密。然後把該資訊傳送到伺服器,伺服器session中儲存這這個賬號的驗證碼,伺服器會從資料庫獲取該使用者的密碼和驗證碼進行組合再次加密與前端傳來的明文進行對比判斷。

好,接著讓我們分析為什麼安全,因為驗證碼是一次性的,, 所以,你在網路層拿到本次的請求之後,無法做 重放攻擊, 因為驗證碼是不正確的.而當你獲取新的驗證碼, 但你並不知道 組合之前的內容[md5(md5(密碼) + 使用者的qq號)] 是什麼 , 所以你無法重新傳送本次請求實現登陸的目的.32位md5 + 4位驗證碼 總計 36位的字串, 你去破解吧. 估計等你掛了你也破解不出來.至於服務端的校驗, 只要將記錄下來的md5值(而不是記錄的明文), 進行同樣的運算, 得到的結果與提交上來的一樣, 即密碼正確.驗證碼的內容是伺服器下發的,而且是一次性的,所以 客戶端無法偽造, 也無法重用.

下面是qq之前網頁的源**片段:

q 網頁上的登陸模組(全程http/get請求).

qq 在登陸時,對使用者輸入的密碼加密的js**為:

function getencryption(password, uin, vcode, ismd5)
白話就是: md5(md5(md5(密碼) + 使用者的qq號) + 驗證碼)

現在你知道如何在http協議下保證密碼安全性了沒有。

然後我們在說說使用者登入後,我們是否要把使用者的密碼儲存到session中。

以前同事寫的密碼修改部分**,發現將使用者登入的密碼存在session中,然後判斷原密碼時直接從session中讀取。

把密碼存在session中安全嗎?

session的儲存方式相對來說比較安全,因為資訊儲存在伺服器的 

而cookie的方式由於對伺服器端來說是不可控的,始終對使用者資訊洩露是乙個危險,但是也有很多採用cookie儲存使用者資訊的,通常是採用加密的方式來進行處理。

我們經常看到很多**設定記住使用者名稱密碼,就是採用cookie的方式 

可行性上,我不建議這麼做。就連sun公司在是設定password的時候,都用transient 來管理, private transient string password;都不希望password序列化掉,所以我們跟不能為了方便而把密碼存入session中來為了方便。

最後我們談談加密的本質:它其實是對原有內容的混淆,目的是提高從表面結果反推達到目的的成本。

在網頁提交(其實所有的通訊都有這個問題)密碼這個問題上,需要有幾個維度來保證安全,

首先是切面的安全性,對於一次提交首先保護的是密碼本身,從最早的base64到md5或是sha都可以做到這一點,但是base64是可逆的,對於密碼本身的保護是很弱的,雜湊演算法解決了這個問題,將不同長度的資料轉換成統一長度的大數字,而理論上這個數字對應無窮多解,但限於密碼的輸入有限制,其實是可逆的,所以從1次混淆的md5變成了3次混淆的sha,但是隨著現代計算機技術的進步,逆運算的成本不斷降低,人們不得已要使用更大的數字來提高這個難度,但是為了向成本和發展妥協,人們不得已使用統一的演算法,在cs時代由於很難侵入到cs兩端,所以相對的雙方使用的演算法是保密的,破解難度相對比較大,bs由於為了保證開放性,特別是js本身就是明文演算法,所以其實只能說防君子不妨小人,所以就有了安全控制項,控制項的唯一目的是用2進製**來隱藏加密的演算法,不知道演算法,也就很難破解原文。

第二維度就是時間,如果密碼一樣加密結果也會一樣,那麼在不使用原文的情況下,可以使用加密過後的資料來模擬使用者登入的動作也是可以的,所以純粹對密碼的加密其實不能解決這個問題,所以有了鹽值,讓同乙個資料在不同情況下結果依舊不一致,但是鹽值需要約定,總會被人找出規律,只是成本又高了點,所以還是不安全,這就引發了通訊安全的問題。所以出現了https使用非對稱加密來保護資料通路上的安全,讓通訊變得不可窺視。但是還有個東西叫木馬,所以人們在輸入上繼續做文章,包括混淆輸入,就是軟鍵盤,好的控制項不會把明文存在記憶體裡,這很重要,以前的vb、dephi密碼控制項都僅僅看不到,實際記憶體裡面都是明文,很容易被病毒和木馬利用,所以一般來說現在最安全的bs系統使用控制項保護輸入,隱藏自己的hash演算法,用https保護通訊。

HTTP協議下保證密碼不被獲取更健壯方式

說到在http協議下使用者登入如何保證密碼安全這個問題 小白可能第一想法就是,使用者在登入頁面輸入密碼進行登入時,前台頁面對使用者輸入的密碼進行加密,然後把加密後的密碼作為http請求引數通過網路發到伺服器。這樣做是無法保證使用者的賬戶安全的,因為稍微懂一點程式設計知識的人就可以通過你傳送的http...

Linux下http協議實現

include include include string h include include socket h include errno h include include include include include include ctype h int main int argc,ch...

Linux下http協議實現

include include include string h include include socket h include errno h include include include include include include ctype h int main int argc,ch...