近年來,國際上揭露的數(shù)據(jù)泄露事件一波比一波嚴重,給企業(yè)造成了嚴重的財產損失。數(shù)據(jù)泄露事件的頻繁發(fā)生引起了很多企業(yè)的反思,最終他們決定通過提升密碼復雜度,給數(shù)據(jù)庫加密等方法保護數(shù)據(jù)安全。
密碼加密的重要性?
還是從脫庫說起,數(shù)據(jù)庫被人拉走了,最可怕的是什么?個人手機、身份證、地址??這些是很重要,但是,其實個人隱私數(shù)據(jù),獲取的難度不是很大,而且不容易直接對一個人造成巨大的傷害,但是,密碼被人知道了,就是很可怕的事情。因為,大部分人不同的系統(tǒng)都是共用密碼。這個錯誤比較低級,但是很常見,所以,密碼,是被脫庫后最容易被人利用。所以,密碼是必須加密的,不把用戶密碼加密的系統(tǒng)和公司,都該判刑。
密碼管理的入門要求
密碼管理產品級別的需求,大家都能看到的是,提升密碼的復雜度和管理策略,一般包括:
密碼加密保存,并且是不可逆的。
密碼更長更復雜。如:密碼長度大于8位,必須是大小寫字母和數(shù)字的組合。
定期修改密碼策略。
登錄輸入密碼錯誤多次,需要輸入驗證碼,甚至是鎖定賬戶。
以上都是一些基礎,但是非常有效的方案,這些產品設計不是我們討論的重點,我們重點說說具體的實現(xiàn)。
在技術上,實際密碼我們是怎么存儲的呢?
String password=MD5("明文")
對用戶的輸入進行MD5加密后,就直接保存在數(shù)據(jù)庫,可能15年前這還是比較安全的存儲方式,但是現(xiàn)在,MD5已經不再安全,越是簡單的密碼,被撞庫獲取到原文的可能性非常的高,所以直接使用MD5加密后保存密碼,顯然已經是非常不安全的方式了。
密碼+salt
前文說道,密碼太短,顯然已經不安全了,那么為了提升負責度,就會強制把用戶的密碼變得更加復雜,于是,就產生了密碼加salt的方案。salt肯定是需要一個比較的復雜的字符串,長度可以長一點。而且最好是,每個用戶的salt是不一樣的。以前的數(shù)據(jù)庫結構是:
ID用戶名密碼
1user134234sdfse2342dggs234s2user2d34desf3432sdf23423sdf
那么比較安全的方式應該是:
ID用戶名密碼salt
1user1sdf452342sdfsd23234sdf982934&7934708hHG12&%&()()()IUHUHGggifiknsdf
2user2234df3234sdf234asfddsd&&8uhhhkKHKl9(7KBKH&……)adksjknklasdlfkjkkkkk
String password=SHA1("明文"+salt);
這里,我們用了相對而言撞庫難度比較大的SHA1的加密方式來取代MD5加密,這樣基本就是一個比較安全的密碼了,即使數(shù)據(jù)被脫庫了,撞庫也很基本不可能破解出明文。
但是,這樣就真的安全了嗎?不一定,我們還少了傳輸加密以及客戶端加密。
客戶端和傳輸加密
首先我們說說傳輸加密,其實,這個現(xiàn)在已經有很標準的解決方案——https,這里我們就不多說了。
我們主要所屬說說客戶端加密:
可能大家覺得有了傳輸加密了,實際客戶端加密也不太重要,顯然不是,這里有個很重要的場景就容易出現(xiàn)風險:
日志。大家的系統(tǒng)都會統(tǒng)一記錄日志,針對密碼這類敏感的信息,如果記錄了日志,而且大家記錄的都是用戶輸入的明文,這樣非常危險。
內網劫持。如果數(shù)據(jù)還沒有到公網,在內網就被劫持了,有可能暴露明文的密碼。
所以,客戶端加密也是很有必要的?,F(xiàn)在的前端技術都是支持MD5加密,所以我們就在前端對用戶的數(shù)據(jù)進行了MD5加密。
客戶端代碼:
var password=md5("明文");
String password=SHA1("客戶端MD5加密后的支付"+salt);
實際,這樣最終存在數(shù)據(jù)庫的,就是一個做了雙重加密的支付。網絡傳輸和日志記錄的就是單次加密的字符,整體的安全度就非常高了。
總結
這樣,一個好的密碼體系應該就是這樣了:
客戶端MD5針對用戶輸入的明文加密后提交到服務端。
服務端根據(jù)用戶生成一個復雜的隨機salt。
根據(jù)隨機salt和接收到的密碼,sha1加密,生成密碼保存到數(shù)據(jù)庫。
這是一篇非常基礎的文章,但是卻被很多的開發(fā)和產品忽略,風險總在一念之間。安全永遠是一個相對的概念,我們只能提升破解安全的成本,無法做到絕對的安全。
(原標題:談談系統(tǒng)密碼存儲策略)