update 2018-06-04php
2015年出的一個規範 JSON Web Token (JWT) https://tools.ietf.org/html/rfc7519
css
JWT 官網: https://jwt.io/
html
八幅漫畫理解使用JSON Web Token設計單點登陸系統: http://blog.leapoahead.com/2015/09/07/user-authentication-with-jwt/
linux
JSON Web Encryption (JWE) : https://tools.ietf.org/html/rfc7516
android
JSON Web Signature (JWS) : https://tools.ietf.org/html/rfc7515
git
update 2017-9-6 github
微信交互協議和加密模式研究:https://github.com/hengyunabc/hengyunabc.github.io/files/1280081/wechat.pdf算法
---數據庫
移動App該怎樣保存用戶password?瀏覽器
這個實際上和桌面程序是同樣的。
參考:http://bbs.pediy.com/archive/index.php?t-159045.html,
桌面QQ在2012的時候把passwordmd5計算以後,保存到本地加密的Sqlite數據庫裏。
參考:http://blog.csdn.net/androidsecurity/article/details/8666954
手機淘寶是經過本地DES加密,再把password保存到本地文件中的,假設拿到ROOT權限,能破解出password明文。
參考:http://www.freebuf.com/tools/37162.html
我實際測試了下。可以輕鬆獲得所有賬號的password明文。
參考:http://blog.csdn.net/lqhbupt/article/details/7787802
linux是經過加鹽(salt),再hash後,保存到/etc/shadow文件中的。
貌似曾經的發行版是md5 hash,如今的發行版都是SHA-512 hash。
linux用戶password的hash算法: http://serverfault.com/questions/439650/how-are-the-hashes-in-etc-shadow-generated
其實是調用了glic裏的crypt函數,可以在man手冊裏查看相關的信息。
可以用如下的命令來生成:
mkpasswd --method=SHA-512 --salt=xxxx
當中salt參數,可以本身設置,最好是隨機生成的。
可以用 mkpasswd --method=help 來查看支持的算法。
看完上面一些軟件的作法以後,咱們來探討下,用戶password該怎樣保存。還有能作到哪一種程度?
這個其實是從用戶的角度出發。即便數據泄露了。影響降到最低。
這點對於移動設置是很是重要的。比如今天用戶連到了一個惡意的wifi,假設攻擊者截獲到請求,要防止攻擊者潛伏几天,或者幾個月以後的攻擊。
必須要讓請求的憑據在一天或者幾天內失效。
假如不加鹽,那麼攻擊者可以依據相同的hash值獲得很是多信息。
比方站點1的數據庫泄露了,攻擊者發現用戶A和用戶B的hash值是同樣的,而後攻擊者經過其餘途徑拿到了用戶A的password。那麼攻擊者就可以知道用戶B的password了。
或者攻擊者經過彩虹表。暴力破解等方式可以直接知道用戶的原來password。
因此。每個用戶的salt值都要是不同的,這點參考linux的/etc/shadow文件就知道了。
應該用哪一種算法來存儲?
從上面的資料來看。手機淘寶是本地DES對稱加密,顯然很是easy就可以破解到用戶的真實password。
QQ也是對稱加密的數據庫裏,存儲了用戶password的md5值。
顯然對稱加密算法都是可以逆向獲得原來的數據的。那麼咱們嘗試用非對稱加密算法,比方RSA來傳輸用戶的password。
那麼用戶登錄的流程就變爲:
有的人會說。假設server的私鑰泄露怎麼辦?
server端換個新的密鑰,強制client下載新的公鑰或者升級。
可以考慮有一個專門的硬件來解密,這個硬件僅僅負責計算。私鑰是一次性寫入不可讀取和改動的。搜索 rsa hardware,貌似的確有這種硬件。
固然。即便真的私鑰泄露,世界同樣運轉。像OpenSSL的心血漏洞就可能泄露server私鑰。但你們日子同樣過。
非對稱加密算法的優勢:
這點其實是怎樣讓client保存的加密串及時的失效。
比方:
攻擊者是否會潛伏很是久?
如下提出一種 salt + 非對稱加密算法的方案來解決問題:
同理,假設某木馬大規模竊取到了大量的用戶本地加密串,那麼可以把緩存中所有用戶的salt都清除,那麼所有用戶都要又一次登錄。注意用戶的password不用改動。
注意,爲了簡化描寫敘述,上面提到的用戶的password,可以是先用某個hash算法hash一次。
瀏覽器的登錄過程比較簡單,僅僅要用RSA公鑰加密password就可以了。
防止中間人截取到明文的password。
App因爲要實現本身主動登錄功能。因此一定要保存一些憑據。因此比較複雜。
App登錄要實現的功能:
這裏推斷時間,主要是防止攻擊者截取到加密串後。可以長久地利用這個加密串來登錄。
再把加密結果返回給client。
屢次md5或者md5 + sha1是沒什麼效果的。
RSA算法最好選擇2048位的。
搜索" rsa 1024 crack"有很是多相關的結果,google已經將其SSL用的RSA算法升級爲2048位的。
怎樣防止登錄過程的中間人攻擊。可以參考,魔獸世界的叫SPR6的登錄算法。
對於網頁登錄,可以考慮支持多種方式:
嚴格要求的應用,最好用JS實現RSA加密。在github上找到的一個JS RSA庫:https://github.com/travist/jsencrypt
server用salt(存數據庫的) + hash算法來保存用戶的password。
用salt(存緩存的,注意和上一行的salt是不一樣的)+ RSA算法來加密用戶登錄的憑證。
這樣server可以靈活控制風險,控制用戶登錄憑據的有效期,即便用戶數據泄露。也不須要改動password。