scram是密碼學中的一種認證機制,全稱salted challenge response authentication mechanism。
scram適用於使用基於『使用者名稱:密碼』這種簡單認證模型的連線協議。
scram是乙個抽象的機制,在其設計中需要用到乙個雜湊函式,這個雜湊函式是客戶端和服務端協商好的,包含在具體的機制名稱中。比如scram-sha1,使用sha1作為其雜湊函式。
基於『使用者名稱:密碼』這種簡單認證模型的協議中,客戶端和服務端都知道乙個使用者名稱(username)對應乙個密碼(password)。在不對通道進行加密的前提下,無論是直接使用明文傳輸『username:password』,還是給password加個雜湊的方法都low爆了,很容易被黑客攻擊。乙個安全性高的認證機制起碼應該是具備雙向認證的,即:
服務端需要驗證連線上來的客戶端知道對應的password
客戶端需要知道這個聲稱是服務端的人是真正的服務端
我們來看看scram是怎麼做的。
服務端使用乙個salt和乙個iteration-count,對password進行加鹽雜湊(使用h表示雜湊函式,這裡就是sha1,iteration-count就是雜湊迭代次數),得到乙個password[s]:
_password[s] = h(password, salt, iteration-count)_
服務端拿這個password[s]分別和字串『client key』和『server key』進行計算hmac摘要,得到乙個key[c]和乙個key[s]:
_key[c] = hmac(password[s], "client key")_
_key[s] = hmac(password[s], "server key")_
服務端儲存username、h(key[c])、key[s]、salt和iteration-count,沒有儲存真正的password
客戶端傳送client-first-message給服務端,包含username和client-nonce,其中client-nonce是客戶端隨機生成的字串
服務端返回客戶端server-first-message,包含salt,iteration-count和client-nonce|server-nonce,其中server-nonce是服務端隨機生成的字串
客戶端傳送client-final-message給服務端,包含client-nonce|server-nonce和乙個proof[c]。這個proof[c]就是客戶端的身份證明。首先構造出這次認證的變數auth如下:
_auth = client-first-message, server-first-message, client-final-message(without proof[c])_
然後使用從服務端獲取的salt和iteration-count,根據已知的password計算出加鹽雜湊password[s],然後根據password[s]得到key[c],再拿這個key[c]和auth變數經過如下計算得到:
_proof[c] = key[c] xor hmac(h(key[c]), auth)_
服務端使用其儲存的h(key[c])和auth計算hmac摘要,再和proof[c]進行異或,得出key[c],再對這個key[c]進行雜湊,和其儲存的h(key[c])進行比較是否一致。如果一致,則客戶端的認證通過,服務端接下來會構造乙個proof[s]用來向客戶端證明自己是服務端:
_proof[s] = hmac(key[s], auth)_
客戶端使用password[s]得到key[s],然後使用相同演算法計算key[s]和auth的hmac摘要,驗證服務端傳送過來的proof[s]是否和計算出來的一致,從而認證服務端的身份。
q:proof[c]為什麼不能是和proof[s]一樣使用hmac(key[c], auth)算得?
a:服務端沒有儲存key[c],而是儲存h(key[c]),這是因為如果服務端的key[c]洩露,那麼黑客可以輕易構造出proof[c],從而偽裝成客戶端了。
q:那麼直接使用hmac(h(key[c]), auth)呢?
a:同樣,如果服務端的h(key[c])洩露,黑客又可以輕易構造出proof[c],從而偽裝成客戶端了。因此必須要加上key[c]的異或,從而證明客戶端知道key[c]的值。
q:但是如果服務端的h(key[c])洩露,再通過網路洩露了proof[c]和auth,就可以根據proof[c]和hmac(h(key[c]), auth)異或得到key[c]了?
q:nonce的作用?
a:client-nonce和server-nonce都是隨機生成的字串,這主要是為了每次認證都有個不同的auth變數,以防止被重放攻擊。
分析下以下幾種情況下scram的安全性:
improved password-based authentication in mongodb 3.0: scram explained - pt. 1
improved password-based authentication in mongodb 3.0: scram explained (part 2)
維基百科:salted challenge response authentication mechanism
阿里雲mongodb雲服務
Spring Boot中使用MongoDB資料庫
前段時間分享了關於spring boot中使用redis的文章,除了redis之後,我們在網際網路產品中還經常會用到另外一款著名的nosql資料庫mongodb。下面就來簡單介紹一下mongodb,並且通過乙個例子來介紹spring boot中對mongodb訪問的配置和使用。mongodb是乙個基...
Spring Boot中使用MongoDB資料庫
前段時間分享了關於spring boot中使用redis的文章,除了redis之後,我們在網際網路產品中還經常會用到另外一款著名的nosql資料庫mongodb。下面就來簡單介紹一下mongodb,並且通過乙個例子來介紹spring boot中對mongodb訪問的配置和使用。mongodb是乙個基...
python 中使用mongodb的封裝
from pymongo import mongoclient class mongohelp object mongodb增刪改查的操作 client mongoclient host localhost port 27017 col client goods book classmethod d...