Passwords

如何在 JavaScript 中安全地異或兩個密碼?

  • July 4, 2022

以下方法安全嗎?

計劃在將結果提供給 Argon2 之前使用實現對兩個密碼片語進行異或。

const xor = (a: string, b: string) => {
 if (a.length > b.length) {
   b = `${b}${b.substring(0, a.length - b.length)}`
 } else if (b.length > a.length) {
   a = `${a}${a.substring(0, b.length - a.length)}`
 }
 let result = ""
 for (let index = 0; index < a.length; index++) {
   result += (
     parseInt(a.charAt(index), 16) ^ parseInt(b.charAt(index), 16)
   ).toString(16)
 }
 return result
}

不,在這種情況下,XOR 幾乎不是答案。

例如,使用 XOR 很可能是密碼的某些值ab相互抵消。如果我是攻擊者,我首先要做的就是嘗試所有零字元串到一定大小,因為這將指示相同的密碼。然而,這只是可能遇到的最明顯的問題。


實際上,只是將密碼串聯起來,以及密碼大小的一些指示或作為其中至少一個分隔符的唯一值將是一個更好的主意。需要該大小以提供稍微更高的安全性,否則一些密碼可能會相互溢出,例如somethingcompletely並會創建與anddifferent相同的字元串。但是,簡單地包含一個特殊字元就可以解決這個問題:並且確實是不同的字元串。當然,您可以使用不可列印的字元(例如ASCII 單元分隔符)而不是 Unicode owl,但請確保它不會在過程中的某個地方被丟棄。something``completelydifferent``somethingcompletely🦉different``something🦉completelydifferent

這是 Argon2 中的初始計算,之後不再使用密碼。如您所見,它直接散列大部分輸入數據,包括密碼。對於其他一些 PBKDF,例如 PBKDF2,執行初始散列可能是有意義的,但對於 Argon2,此初始散列已包含在算法中。

buffer ← parallelism ∥ tagLength ∥ memorySizeKB ∥ iterations ∥ version ∥ hashType
    ∥ Length(password)       ∥ Password
    ∥ Length(salt)           ∥ salt
    ∥ Length(key)            ∥ key
    ∥ Length(associatedData) ∥ associatedData
 H0 ← Blake2b(buffer, 64) //default hash size of Blake2b is 64-bytes

(來源:維基百科

由於這個初始散列,Argon2 中的密碼大小沒有真正的限制(不經常使用 4GiB 或更大的密碼)。


請注意,此答案直接針對 XOR 構造。很可能存在不同的策略,這些策略甚至比這裡針對特定目的提出的策略更好(例如,對兩個密碼分別使用 Argon2 並在連接結果上使用 HKDF)。

引用自:https://crypto.stackexchange.com/questions/100840