2017-08-16 16 views
1

在我的系統中,每個用戶可以有多個api密鑰。我想散列api鍵並將它們的散列存儲在數據庫中。我爲此使用了愛荷星。Phoenix/Elixir中api密鑰的散列以及對此使用comeonin

1)是否明智地存儲api密鑰的哈希值,而不是其原始的原始值?

2)當一個api請求進來時,它只有一個普通的api鍵值,沒有用戶的電子郵件 - 這是我設計的系統。

我該如何檢查api密鑰是否有效?我將不得不這樣做 - 重新計算哈希值?

given_api_plain_key = get_key_from_request() 

# re-hash it again 
# but how about the original salt??? 

given_api_hash_key = Comeonin.Bcrypt.hashpwsalt(given_api_plain_key) 


case Repo.get_by(ApiKey, key_hash: given_api_hash_key) do 
    nil -> IO.puts("not found") 
    a -> IO.puts("gooood") 
end 

或者還有更好的方法嗎?

+0

bcrypt是一個很好的密碼解決方案:因爲密碼的熵值較低,所以bcrypt通過減少哈希計算速度來減緩蠻力攻擊。但API密鑰可能具有較高的熵,因此強力攻擊不是這種風險。總結:比如SHA256更快的功能可能更適合您的設計。 – TheGreatContini

+0

@TheGreatContini,好的,這是答案的一部分。 – Jily

+0

繼續@ TheGreatContini的評論,只要你生成API密鑰,並且它們很長且隨機,我就不會看到任何散列需要。另見https://security.stackexchange.com/questions/18572/is-it-okay-for-api-secret-to-be-stored-in-plain-text-or-decrypt-able。 – Dogbert

回答

1

(1)是否明智地存儲api密鑰的哈希值,而不是其原始的原始值?

您的目標似乎是爲了防止有人訪問您的數據庫(例如,通過SQL注入,命令注入或系統上的反向shell)可能發生的巨大折衷。在這種情況下,是的,這是明智的,特別是如果每​​個用戶都有不同的API密鑰。但this link值得一讀,可能會影響您的決定。

(2)如何檢查api密鑰是否有效?

很明顯,您需要散列輸入並查看是否與數據庫中的某些內容匹配。

(3)執行。

您不想應用與密碼相同的保護。密碼本質上往往熵低,因此我們需要像bcrypt這樣的工具來處理它們。 Bcrypt設計緩慢(以防止暴力攻擊),並使用鹽來幫助選擇不當的密碼的安全性。

API密鑰不應該有低熵,因此您不需要慢函數來處理它們。事實上,緩慢的功能會帶來DoS風險,因此您絕對不想對每個請求都進行加密。鹽分也會使您的用例變得複雜(當您知道誰在提供輸入時鹽會起作用,但在您的情況下知道它是從哪裏來的)。

簡短的回答:只需使用SHA256,不需要鹽。