Web登錄安全詳解

作者:letcafe
文章:Web登錄其實沒那么簡單

1. 一個簡單的HTML例子看看用戶信息安全

標準的HTML語法中勾徽,支持在form表單中使用<input></input>標簽來創(chuàng)建一個HTTP提交的屬性,現(xiàn)代的WEB登錄中鲫竞,常見的是下面這樣的表單:

<form action = "http://localhost:8080/Application/login" method = "POST">
    用戶名:<input id="username" name="username" type="text" />
    密碼:<input id="password" name="password" type="password" />
    <button type="submit">登陸</button>
</form>

form表單會在提交請求時,會獲取form中input標簽存在name的屬性璧瞬,作為HTTP請求的body中的參數(shù)傳遞給后臺卢厂,進行登錄校驗告嘲。


例如我的賬號是user1稳强,密碼是123456,那么我在提交登錄的時候會給后臺發(fā)送的HTTP請求如下(Chrome或者FireFox開發(fā)者工具捕獲间涵,需開啟Preserve log):


可以發(fā)現(xiàn)即便password字段是黑點仁热,但是本機仍以明文的形式截獲請求。

2. HTTP協(xié)議傳輸直接暴露用戶密碼字段

在網(wǎng)絡傳輸過程中勾哩,被嗅探到的話會直接危及用戶信息安全抗蠢,以Fiddler或Wireshark為例,發(fā)現(xiàn)捕獲的HTTP報文中包含敏感信息:


3. 使用加密算法能保證密碼安全嗎思劳?

WEB前端可以通過某種算法迅矛,對密碼字段進行加密后,在將密碼作為Http請求的內(nèi)容進行提交敢艰,常見的包括對稱和非對稱加密诬乞。

對稱加密:采用對稱密碼編碼技術(shù),它的特點是文件加密和解密使用相同的密鑰加密钠导。

非對稱加密:需要兩個密鑰震嫉,公開密鑰(publickey)和私有密鑰(privatekey)。公開密鑰與私有密鑰是一對牡属,如果用公開密鑰對數(shù)據(jù)進行加密票堵,只有用對應的私有密鑰才能解密;如果用私有密鑰對數(shù)據(jù)進行加密逮栅,那么只有用對應的公開密鑰才能解密悴势。

3.1 使用對稱加密

加密解密在前后臺協(xié)商后窗宇,似乎是個不錯的辦法,比如特纤,前臺使用一個字符串位移+字符串反轉(zhuǎn)的簡單方法(舉個例子军俊,當然不能這么簡單)。那么捧存,如果原密碼123456先移位:

123456-->456123

再進行反轉(zhuǎn):

456123-->321654

那么這樣簡單的方法似乎可以混淆原密碼粪躬,并且輕松由后臺進行相反操作復原。但是這有兩個缺點:

  1. 前后端加密解密需要同時修改代碼昔穴;
  2. 前端加密無非是寫在JS里镰官,但是JS有風險被直接破解從而識別加密方法。

3.2 非對稱加密HTTPS就一定是安全的嗎吗货?

非對稱加密有著公鑰私鑰的存在泳唠,公鑰可以隨意獲取,私鑰是用來對公鑰解密的本地存儲宙搬,通過公私鑰的機制似乎可以保證傳輸加密并且乃至現(xiàn)在還在使用的HTTPS就是基于這個原理笨腥。
但是HTTPS就一定安全嗎?HTTP存在兩種可能的風險:

  1. HTTPS可以保證傳輸過程中的信息不被別人截獲害淤,但是細細思考下扇雕,HTTPS是應用層協(xié)議,下層采用SSL保證信息安全窥摄,但是在客戶端和服務端镶奉,密文同樣是可以被截獲的;
  2. HTTPS報文在傳輸過程中崭放,如果客戶端被惡意引導安裝“中間人”的WEB信任證書哨苛,那么HTTPS中的“中間人攻擊”一樣會將明文密碼泄露給別人。

4. 結(jié)論是币砂,無論HTTP還是HTTPS建峭,密碼必須密文傳輸

想想HTTPS也不能一定保障用戶密碼信息,那么就應該考慮在應用層之上再繼續(xù)對密碼進行保護决摧,也就是編寫代碼來進行控制亿蒸,而不依賴特定協(xié)議,比較容易想到的就是利用不可逆加密散列函數(shù)MD5(string)掌桩,用戶在注冊輸入密碼的時候边锁,就存儲MD5(password)值,并且在WEB端先進行MD5(password)波岛,然后將密碼傳輸至后臺茅坛,與數(shù)據(jù)庫中的密文進行比較(PS:MD5函數(shù)在指定位數(shù)的情況下,對相同字符串運算值相同)则拷。優(yōu)點比較明顯:

  1. 保證了用戶數(shù)據(jù)庫內(nèi)部的密碼信息安全贡蓖;
  2. 傳輸過程中無論如何都不會使得用戶的密文被破解出原密碼曹鸠;
  3. 簡單高效,執(zhí)行以及編碼難度都不大斥铺,各種語言都提供MD5支持彻桃,開發(fā)快。

5. 那太好了仅父!這樣可以省下HTTPS的錢了叛薯,真是這樣嗎浑吟?

回到開頭的例子:用戶輸入的用戶名是:user1笙纤,密碼是:123456,那么不管在什么協(xié)議之下组力,可以看到實際發(fā)送的HTTP/HTTPS報文在MD5處理后是這樣的:


沒錯省容,加密登錄成功了。但是燎字,當我們慶祝密碼安全的時候腥椒,發(fā)現(xiàn)賬戶的錢突然不翼而飛。這是為什么呢候衍?黑客卻笑的很開心:因為他們并不一定要獲取到你的密碼明文笼蛛,如果直接截獲你的密碼密文,然后發(fā)送給服務器不是一樣可以登錄嗎蛉鹿?因為數(shù)據(jù)庫里的不也是MD5(password)的一樣的密文嗎滨砍?HTTP請求被偽造,一樣可以登錄成功妖异,從而攫取其他的數(shù)據(jù)或者轉(zhuǎn)走余額惋戏。

這怎么辦?其實并不難,有很多種解決方法他膳?其實原理都是類似的:那就是服務器緩存生成隨機的驗證字段响逢,并發(fā)送給客戶端,當客戶端登錄時棕孙,把這個一并字段傳給服務器舔亭,用于校驗。

5.1 方案一:驗證碼

MVC場景蟀俊∏掌蹋控制器將把數(shù)據(jù)的Model封裝到View中,這種存在Session的連接方式欧漱,允許了在Session中存取信息职抡。那么我們可以利用一些開源的驗證碼生成工具,例如JAVA中的Kaptcha误甚,在服務端存放生成一個驗證碼值以及一個驗證碼的生成圖片缚甩,將圖片以Base64編碼谱净,并返回給View,在View中解碼Base64并加載圖片擅威,并于用戶下次登錄時再進行比對壕探。

5.2 方案二:token令牌

前后端分離場景。現(xiàn)在非常流行的前后端分離的開發(fā)模式大大提高了項目的開發(fā)效率郊丛。職責李请、分工明確,但是由于HTTP是無狀態(tài)的(就是這一次請求并不知道上一次請求的內(nèi)容)厉熟,當用戶登錄時导盅,根據(jù)用戶的username作為key,生成隨機令牌(例如UUID)作為value緩存在Redis中揍瑟,并且將token返回給客戶端白翻,當客戶端登錄時,將完成校驗绢片,并且刪除Redis中的那條緩存記錄滤馍。

那么每次從服務器中獲取認證的token,確實能保證HTTP請求是由前端傳回來的了底循,因為token在每次登陸后都會刪除并被重置巢株,會導致黑客嘗試重放賬號密碼數(shù)據(jù)信息來登陸的時候?qū)е聼o法成功登陸。

總而言之熙涤,就是我拿到了賬號以及密碼的密文也登陸不了阁苞,因為,如果請求不包含后臺認證的令牌token灭袁,是個非法請求猬错。

6. 太不容易了!可是還別高興的太早茸歧,當心數(shù)據(jù)被篡改

密碼也加密了倦炒,黑客看不到明文了。加上Token了软瞎,登陸過程也沒法再被截獲重放了逢唤。可是想想這種情況涤浇,你在進行某寶上的網(wǎng)絡支付鳖藕,需要賬號,密碼只锭,金額著恩,token這四個字段進行操作,然后支付的時候你付了1塊錢買了一袋包郵的小浣熊干脆面,某寶結(jié)算結(jié)束后喉誊,你發(fā)現(xiàn)你的賬戶余額被扣了1萬元邀摆。這又是怎么回事呢?

因為即便黑客不登錄伍茄,不操作栋盹,一樣要搞破壞:當請求路由到黑客這邊的時候,截獲數(shù)據(jù)包敷矫,然后也不需要登錄例获,反正賬號密碼都是對的,token也是對的曹仗,那么把數(shù)據(jù)包的字段改改榨汤,搞破壞就可以了,于是把money改成了1萬整葡,再傳給服務器件余,作為受害者就莫名其妙踩了這個坑≡饩樱可這該怎么解決呢?其實原理類似于HTTPS里的數(shù)字簽名機制旬渠,首先科普下什么是數(shù)字摘要以及數(shù)字簽名:

6.1 什么是“數(shù)字摘要”

我們在下載文件的時候經(jīng)常會看到有的下載站點也提供下載文件的“數(shù)字摘要“俱萍,供下載者驗證下載后的文件是否完整,或者說是否和服務器上的文件”一模一樣“告丢。其實枪蘑,數(shù)字摘要就是采用單項Hash函數(shù)將需要加密的明文“摘要”成一串固定長度(128位)的密文,這一串密文又稱為數(shù)字指紋岖免,它有固定的長度岳颇,而且不同的明文摘要成密文,其結(jié)果總是不同的颅湘,而同樣的內(nèi)容信息其摘要必定一致话侧。

因此,“數(shù)字摘要“叫”數(shù)字指紋“可能會更貼切一些闯参≌芭簦“數(shù)字摘要“是HTTPS能確保數(shù)據(jù)完整性和防篡改的根本原因。

6.2 數(shù)字簽名--水到渠成的技術(shù)

假如發(fā)送方想把一份報文發(fā)送給接收方鹿寨,在發(fā)送報文前新博,發(fā)送方用一個哈希函數(shù)從報文文本中生成報文摘要,然后用自己的私人密鑰對這個摘要進行加密,這個加密后的摘要將作為報文的”簽名“和報文一起發(fā)送給接收方脚草,接收方首先用與發(fā)送方一樣的哈希函數(shù)從接收到的原始報文中計算出報文摘要赫悄,接著再用發(fā)送方的公用密鑰來對報文附加的數(shù)字簽名進行解密,如果這兩個摘要相同、那么接收方就能確認報文是從發(fā)送方發(fā)送且沒有被遺漏和修改過埂淮!這就是結(jié)合“非對稱密鑰加解密”和“數(shù)字摘要“技術(shù)所能做的事情嚼贡,這也就是人們所說的“數(shù)字簽名”技術(shù)。在這個過程中同诫,對傳送數(shù)據(jù)生成摘要并使用私鑰進行加密地過程就是生成”數(shù)字簽名“的過程粤策,經(jīng)過加密的數(shù)字摘要,就是”數(shù)字簽名“误窖。

因此叮盘,我們可以在WEB端對之前案例中提到的username+MD5(password)+token通過簽名,得到一個字段checkCode霹俺,并將checkCode發(fā)送給服務器柔吼,服務器根據(jù)用戶發(fā)送的checkCode以及自身對原始數(shù)據(jù)簽名進行運算比對,從而確認數(shù)據(jù)是否中途被篡改丙唧,以保持數(shù)據(jù)的完整性愈魏。

7. 總結(jié)

看似非常簡單的WEB登錄,其實里面也存在著非常多的安全隱患想际。這些安全完善的過程是在一個實際WEB項目中遇到的培漏,上面的分析演化是在應對項目安全的檢查中所提出的解決方案,多少會有很多不足的地方胡本,希望一起交流探討牌柄,共同進步!

補充1:JS加密函數(shù)存在被破解

感謝園友mysgk指出完整性檢驗中關(guān)于JS加密函數(shù)存在被破解的問題:

問題描述:

如果黑客通過閱讀前端js源碼,發(fā)現(xiàn)加密算法,是否意味他可以構(gòu)造可以
被服務端解密的checkCode 來欺騙服務端呢 ?

我想了下侧甫,應該也是很多網(wǎng)站也在采取的策略:

摘要或加密JS算法不直接以靜態(tài)文件的形式存在瀏覽器中珊佣,而是讓WEB端去請求Server,服務器可以根據(jù)隨機令牌token值決定返回一個相應隨機的加密策略披粟,以JS代碼響應的方式返回咒锻,在異步請求響應中,加載JS摘要算法守屉,這樣客戶端就可以動態(tài)加載數(shù)字摘要策略惑艇,保證無法仿造。

補充2:MD5存在隱患的問題

感謝園友EtherDream提出MD5已經(jīng)過時胸梆,并且存在不安全的問題:

問題描述:

用MD5敦捧、SHA256 處理密碼的過時了。碰镜【ぢ眩。現(xiàn)在 PBKDF绪颖、bcrypt 都在過時中秽荤。

  1. 本文重點側(cè)重于方法思路的介紹甜奄,并不一定是要使用MD5函數(shù),可以使用其他的方式窃款。
  2. MD5存在隱患课兄,之前確實沒有考慮太多,不過非常感謝園友指出晨继,確實是這樣的烟阐,主要思想是:

對于MD5的破解,實際上都屬于【碰撞】紊扬。比如原文A通過MD5可以生成摘要M蜒茄,我們并不需要把M還原成A,只需要找到原文B餐屎,生成同樣的摘要M即可檀葛。
設MD5的哈希函數(shù)是MD5(),那么:
MD5(A) = M
MD5(B) = M
任意一個B即為破解結(jié)果腹缩。
B有可能等于A屿聋,也可能不等于A。

大概意思也就是藏鹊,截獲了MD5加密后的密文润讥,一樣可以,找到一個不是原密碼伙判,但是加密后可以登陸成功的“偽原文”象对。

CSDN有一篇關(guān)于MD5風險的博客寫的非常好,推薦一下:MD5算法如何被破解

從中可以看到一點宴抚,MD5函數(shù)確實能被反向“破解”,但是這個“破解”只是找到一個經(jīng)過MD5運算后得到相同結(jié)果的原文甫煞,并非是用戶的明文密碼菇曲。但是這樣會被破解登錄的可能,確實是需要采用更完善的算法進行加密抚吠,再次感謝常潮!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市楷力,隨后出現(xiàn)的幾起案子喊式,更是在濱河造成了極大的恐慌,老刑警劉巖萧朝,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件岔留,死亡現(xiàn)場離奇詭異,居然都是意外死亡检柬,警方通過查閱死者的電腦和手機献联,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人里逆,你說我怎么就攤上這事进胯。” “怎么了原押?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵胁镐,是天一觀的道長。 經(jīng)常有香客問我诸衔,道長盯漂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任署隘,我火速辦了婚禮宠能,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘磁餐。我一直安慰自己违崇,他們只是感情好,可當我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布诊霹。 她就那樣靜靜地躺著羞延,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脾还。 梳的紋絲不亂的頭發(fā)上伴箩,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天,我揣著相機與錄音鄙漏,去河邊找鬼嗤谚。 笑死,一個胖子當著我的面吹牛怔蚌,可吹牛的內(nèi)容都是我干的巩步。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼桦踊,長吁一口氣:“原來是場噩夢啊……” “哼椅野!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起籍胯,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤竟闪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后杖狼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體炼蛤,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年本刽,在試婚紗的時候發(fā)現(xiàn)自己被綠了鲸湃。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片赠涮。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖暗挑,靈堂內(nèi)的尸體忽然破棺而出笋除,到底是詐尸還是另有隱情,我是刑警寧澤炸裆,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布垃它,位于F島的核電站,受9級特大地震影響烹看,放射性物質(zhì)發(fā)生泄漏国拇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一惯殊、第九天 我趴在偏房一處隱蔽的房頂上張望酱吝。 院中可真熱鬧,春花似錦土思、人聲如沸务热。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽崎岂。三九已至,卻和暖如春闪湾,著一層夾襖步出監(jiān)牢的瞬間冲甘,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工途样, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留江醇,地道東北人。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓何暇,卻偏偏與公主長得像嫁审,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子赖晶,可洞房花燭夜當晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容