簡體   English   中英

Argon2 庫,可以在沒有秘密的情況下對密碼進行哈希處理,並且使用看起來不可解析的隨機鹽

[英]Argon2 library that hashes passwords without a secret and with a random salt that doesn't appear parseable

我正在尋找 Python 應用程序中 hash 密碼的不同替代方案。 首先,我決定使用 Flask-bcrypt ( https://github.com/maxcountryman/flask-bcrypt ),但后來決定使用 Argon2。 Python 最流行的 Argon2 綁定是 argon2-cffi ( https://github.com/hynek/argon2-cffi )。

根據其文檔( https://argon2-cffi.readthedocs.io/en/stable/api.html ),我需要做的就是使用 3 種方法:

  • hash到 hash 一個密碼
  • verify以將密碼與 hash 進行比較
  • check_needs_rehash以查看在更改散列參數后是否應重新散列密碼

有兩件事讓我困惑。

1)鹽是隨機的,使用os.urandom 因此,我想知道verify方法是否能夠以某種方式從 hash 中提取鹽? 或者換句話說,由於我對鹽是什么沒有發言權並且無法保存它, verify方法實際上如何將任何密碼與使用隨機鹽散列的密碼進行比較? 我是否應該自己從hash的返回值中解析鹽,並將其與散列值分開存儲? 或者 hash 是否應該按原樣存儲在文檔中,不受影響,並且 Argon2 能夠以某種方式驗證密碼? 如果 Argon2 確實可以從 hash 中提取鹽,那么在這種情況下使用鹽如何更安全,因為獲得散列密碼的敵對實體也應該能夠提取鹽?

2)默認情況下,我不向hash方法提供任何秘密,而是密碼本身似乎被用作秘密。 這安全嗎? 我不提供散列方法的秘密有什么缺點?

1)鹽是隨機的,使用os.urandom 因此,我想知道verify方法是否能夠以某種方式從 hash 中提取鹽?

hash方法返回一個字符串,該字符串編碼鹽、參數和密碼 hash 本身,如文檔所示:

>>> from argon2 import PasswordHasher
>>> ph = PasswordHasher()
>>> hash = ph.hash("s3kr3tp4ssw0rd")
>>> hash  
'$argon2id$v=19$m=102400,t=2,p=8$tSm+JOWigOgPZx/g44K5fQ$WDyus6py50bVFIPkjA28lQ'
>>> ph.verify(hash, "s3kr3tp4ssw0rd")
True

該格式在 Argon2 參考實現中進行了總結; 也許還有其他參考資料。 在這種情況下:

  1. $argon2id$...

    hash 是 Argon2id,這是每個人都應該使用的特定 Argon2 變體(結合了 Argon2i 的側通道電阻和更難破解的 Argon2d)。

  2. ...$v=19$...

    hash的版本是0x13(十進制19),意思是Argon2 v1.3,密碼哈希競賽采用的版本。

  3. ...$m=102400,t=2,p=8$...

    memory使用為100MB(102400KB),時間為2次迭代,並行度為8路。

  4. ...$tSm+JOWigOgPZx/g44K5fQ$...

    鹽是tSm+JOWigOgPZx/g44K5fQ (base64),或者b5 29 be 24 e5 a2 80 e8 0f 67 1f e0 e3 82 b9 7d (十六進制)。

  5. ...$WDyus6py50bVFIPkjA28lQ

    密碼 hash 本身就是WDyus6py50bVFIPkjA28lQ (base64),或者58 3c ae b3 aa 72 e7 46 d5 14 83 e4 8c 0d bc 95 (十六進制)。

verify方法采用該字符串和一個候選密碼,使用所有編碼參數重新計算密碼 hash,並將其與編碼密碼 hash 進行比較。

如果 Argon2 確實可以從 hash 中提取鹽,那么在這種情況下使用鹽如何更安全,因為獲得散列密碼的敵對實體也應該能夠提取鹽?

salt 的目的是通過簡單地對每個用戶進行不同的處理來減輕多目標攻擊的批量優勢。

  • 如果每個人都使用相同的鹽,那么在給定哈希值的情況下,試圖找到第一個$n$密碼的對手只需要花費大約1 美元/n$的成本,而對手在給定 hash 的情況下試圖找到單個特定密碼將不得不花費花費。 或者,對手可以通過進行昂貴的預計算(彩虹表)來加速破解個人密碼。

  • 但如果每個人都使用不同的鹽,那么批量優勢或預計算優勢就會消失。

在 32 字節字符串中隨機均勻地選擇鹽只是保證每個用戶都有不同的鹽的簡單方法。 原則上,可以想象一個權威機構向世界上的每個人分發一個連續的數字作為他們的 Argon2 鹽,但該系統不能很好地擴展——我的意思不僅僅是你的應用程序可以使用計數權威,而是世界上的每個應用程序都必須使用相同的計數權限,我認為芝麻街的計數太忙了,無法承擔這項工作。

2)默認情況下,我不向hash方法提供任何秘密,而是密碼本身似乎被用作秘密。 這安全嗎? 我不提供散列方法的秘密有什么缺點?

通常密碼就是秘密:如果有人知道密碼,那么他們應該能夠登錄; 如果他們不知道密碼,他們應該被帶到門口!

也就是說,Argon2支持密鑰,它與鹽分開,與密碼分開。

如果您的密碼數據庫和您的應用程序之間存在有意義的安全邊界,因此攻擊者可能會破壞其中一個而不是另一個,那么應用程序可以選擇一個統一的隨機 32 字節字符串作為密鑰,並將其與 Argon2 一起使用這樣密碼 hash 就是密碼function 的密碼。

這樣,轉儲密碼數據庫而不是應用程序密鑰的對手甚至無法測試密碼猜測,因為他們不知道計算密碼 hash 所需的密鑰。

hash的output實際上是hash、Z0800FC577294C45E0B28AD2的一個編碼。 您不需要對其進行任何特殊處理,只需正常存儲即可。

Argon2 是一種密碼散列算法。 它(通常)不需要任何秘密。 這在設計上是安全的。 除了密碼之外,還可以將其與秘密值一起使用,這幾乎不會增加任何安全性。 也可以將其用作密鑰推導 function,這幾乎總是浪費。 這些東西都不會降低安全性,但它們是不必要的,所以不要打擾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM