轉(zhuǎn)載
一、登錄機制
粗略地分析睛挚, 登錄機制主要分為登錄驗證邪蛔、登錄保持、登出三個部分扎狱。登錄驗證是指客戶端提供用戶名和密碼侧到,向服務(wù)器提出登錄請求勃教,服務(wù)器判斷客戶端是否可以登錄并向客戶端確認。 登錄認保持是指客戶端登錄后匠抗, 服務(wù)器能夠分辨出已登錄的客戶端故源,并為其持續(xù)提供登錄權(quán)限的服務(wù)器。登出是指客戶端主動退出登錄狀態(tài)汞贸。容易想到的方案是绳军,客戶端登錄成功后, 服務(wù)器為其分配sessionId, 客戶端隨后每次請求資源時都帶上sessionId著蛙。
1.1 登錄驗證
上述簡易的登錄驗證策略存在明顯的安全漏洞,需要優(yōu)化猎唁。
1.1.1 密碼的傳輸
客戶端第一次發(fā)出登錄請求時帐偎, 用戶密碼以明文的方式傳輸豁生, 一旦被截獲芍殖, 后果嚴重。因此密碼需要加密,例如可采用RSA非對稱加密蒂窒。具體流程如下:
- 客戶端向服務(wù)器第一次發(fā)起登錄請求(不傳輸用戶名和密碼)纬凤。
- 服務(wù)器利用RSA算法產(chǎn)生一對公鑰和私鑰。并保留私鑰蜻底, 將公鑰發(fā)送給客戶端脱惰。
- 客戶端收到公鑰后良蛮, 加密用戶密碼, 向服務(wù)器發(fā)起第二次登錄請求(傳輸用戶名和加密后的密碼)。
- 服務(wù)器利用保留的私鑰對密文進行解密,得到真正的密碼泻仙。
1.1.2 登錄狀態(tài)token
再仔細核對上述登錄流程究抓, 我們發(fā)現(xiàn)服務(wù)器判斷用戶是否登錄橘茉, 完全依賴于sessionId, 一旦其被截獲构挤, 黑客就能夠模擬出用戶的請求矾飞。于是我們需要引入token的概念: 用戶登錄成功后, 服務(wù)器不但為其分配了sessionId, 還分配了token巷蚪, token是維持登錄狀態(tài)的關(guān)鍵秘密數(shù)據(jù)。在服務(wù)器向客戶端發(fā)送的token數(shù)據(jù)啸臀,也需要加密每聪。于是一次登錄的細節(jié)再次擴展穷娱。
- 客戶端向服務(wù)器第一次發(fā)起登錄請求(不傳輸用戶名和密碼)篓叶。
- 服務(wù)器利用RSA算法產(chǎn)生一對公鑰和私鑰。并保留私鑰锥腻, 將公鑰發(fā)送給客戶端幸斥。
- 客戶端收到公鑰后经窖, 加密用戶密碼搬泥,向服務(wù)器發(fā)送用戶名和加密后的用戶密碼芭碍; 同時另外產(chǎn)生一對公鑰和私鑰孽尽,自己保留私鑰, 向服務(wù)器發(fā)送公鑰窖壕; 于是第二次登錄請求傳輸了用戶名和加密后的密碼以及客戶端生成的公鑰。
- 服務(wù)器利用保留的私鑰對密文進行解密杉女,得到真正的密碼瞻讽。 經(jīng)過判斷, 確定用戶可以登錄后熏挎,生成sessionId和token速勇, 同時利用客戶端發(fā)送的公鑰,對token進行加密坎拐。最后將sessionId和加密后的token返還給客戶端烦磁。
- 客戶端利用自己生成的私鑰對token密文解密养匈, 得到真正的token。
1.2 登錄保持
在最原始的方案中都伪, 登錄保持僅僅靠服務(wù)器生成的sessionId: 客戶端的請求中帶上sessionId, 如果服務(wù)器的redis中存在這個id呕乎,就認為請求來自相應的登錄客戶端。 但是只要sessionId被截獲陨晶, 請求就可以為偽造猬仁, 存在安全隱患。
引入token后先誉,上述問題便可得到解決湿刽。 服務(wù)器將token和其它的一些變量, 利用散列加密算法得到簽名后褐耳,連同sessionId一并發(fā)送給服務(wù)器叭爱; 服務(wù)器取出保存于服務(wù)器端的token,利用相同的法則生成校驗簽名, 如果客戶端簽名與服務(wù)器的校驗簽名一致漱病, 就認為請求來自登錄的客戶端买雾。
1.3 TOKEN失效
用戶登錄出系統(tǒng)
失效原理:
在服務(wù)器端的redis中刪除相應key為session的鍵值對。
App登陸保存數(shù)據(jù)流程
App因為要實現(xiàn)自動登陸功能杨帽,所以必然要保存一些憑據(jù)漓穿,所以比較復雜。
App登陸要實現(xiàn)的功能:
- 密碼不會明文存儲注盈,并且不能反編繹解密晃危;
- 在服務(wù)器端可以控制App端的登陸有效性,防止攻擊者拿到數(shù)據(jù)之后老客,可以長久地登陸僚饭;
- 用戶如果密碼沒有泄露,不用修改密碼就可以保證安全性胧砰;
- 可以區(qū)分不同類型的客戶端安全性鳍鸵;比如Android用戶受到攻擊,只會讓Android用戶的登陸失效尉间,IOS用戶不受影響偿乖。
App第一次登陸流程:
- 用戶輸入密碼,App把這些信息用RSA公鑰加密:(用戶名,密碼,時間,mac,隨機數(shù))哲嘲,并發(fā)送到服務(wù)器贪薪。
- 服務(wù)器用RSA私鑰解密,判斷時間(可以動態(tài)調(diào)整1天到7天)眠副,如果不在時間范圍之內(nèi)画切,則登陸失敗。如果在時間范圍之內(nèi)囱怕,再調(diào)用coreservice判斷用戶名和密碼霍弹。
這里判斷時間毫别,主要是防止攻擊者截取到加密串后,可以長久地利用這個加密串來登陸庞萍。
- 如果服務(wù)器判斷用戶成功登陸拧烦,則用AES加密:(隨機salt,用戶名,客戶端類型,時間)忘闻,以(用戶名+Android/IOS/WP)為key钝计,存到緩存里。再把加密結(jié)果返回給客戶端齐佳。
- 客戶端保存服務(wù)器返回的加密串
App自動登陸的流程:
- App發(fā)送保存的加密串到服務(wù)器私恬,(加密串,用戶名炼吴,mac本鸣,隨機數(shù))==>RSA公鑰加密
- 服務(wù)器用RSA私鑰解密,再用AES解密加密串硅蹦,判斷用戶名是否一致荣德。如果一致,再以(用戶名+Android/IOS/WP)為key到緩存里查詢童芹。如果判斷緩存中的salt值和客戶端發(fā)送過來的一致涮瞻,則用戶登陸成功。否則登陸失敗假褪。
不用AES加密署咽,用RSA公鑰加密也是可以的。AES速度比RSA要快生音,RSA只能存儲有限的數(shù)據(jù)宁否。