Encryption

用於身份驗證的加密 AES

  • December 31, 2019

使用這樣的身份驗證策略是否安全:

  • 將密鑰儲存在數據庫中 -crypto.randomBytes(32)
  • 將 IV 和加密數據儲存在使用者 cookie 中 -crypto.randomBytes(16)

cookies.iv根據請求使用, cookies.data,解密加密數據database.key。如果解密成功,請繼續請求。

加密數據是沒有值的隨機字元串。

如果數據庫密鑰被黑客入侵,則無法登錄,因為需要儲存在使用者 cookie 中的 IV。

如果 cookie 被盜,我認為是使用者問題。

我唯一擔心的是,對於某些隨機攻擊者密鑰,有一種方法可以成功解密。對於大多數請求,解密對於性能來說將是沉重的。


cookie加密/解密的範常式式碼:

/**
* @param {string} data dummy
* @param {string} userKey from database or create new
* @return {object} {iv, key, encryptedData}
*/
function encrypt(data, userKey) {
 let key = userKey ? Buffer.from(userKey, 'hex') : crypto.randomBytes(32)
 let iv = crypto.randomBytes(16)
 let cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key), iv)
 let encrypted = cipher.update(data)
 encrypted = Buffer.concat([encrypted, cipher.final()])
 return { iv: iv.toString('hex'), key: key.toString('hex'), encryptedData: encrypted.toString('hex') }
}

/**
* @param {string} iv
* @param {string} key
* @param {string} encryptedData
* @return {string} decrupted dummy data
*/
function decrypt(iv, key, encryptedData) {
 try {
   iv = Buffer.from(iv, 'hex')
   key = Buffer.from(key, 'hex')
   encryptedData = Buffer.from(encryptedData, 'hex')
   let decipher = crypto.createDecipheriv('aes-256-cbc', key, iv)
   let decrypted = decipher.update(encryptedData)
   decrypted = Buffer.concat([decrypted, decipher.final()])
   return decrypted.toString()
 } catch (err) {
   return false
 }
}

關於 IV 的方面已經解決了@Maarten - 恢復 Monica。還有一些問題。

  1. 如果您為以後的所有請求將加密數據儲存在 cookie 中一次,那麼它將不起作用,因為許多使用者會定期清理 cookie 和本地儲存。有些手動執行此操作,有些使用外掛在瀏覽器退出時或每 2-3 小時清理 cookie 和本地儲存。有些使用者甚至無法控制這一點,因為在嚴肅的公司中,使用者沒有管理員權限,並且只能強制使用此類外掛。

  2. 如果您每次都將加密數據設置為 cookie用於登錄目的,那麼清除 cookie 不會破壞您的解決方案。但是,如果攻擊者竊取了密鑰數據庫,那麼他可以輕鬆解密您在登錄期間發送給他的任何內容。

3)使用者應該證明他知道密鑰而不將這個密鑰發送到伺服器的想法是好的。但只有當使用者通過某個通道不是稍後用於身份驗證的通道獲得密鑰時,這才是好的。當您想通過與稍後身份驗證/解密請求相同的通道(相同的 HTTPS 連接)傳輸密鑰時。因此,您沒有更多的安全性。如果沒有任何額外的安全性,這將更加複雜。我會勸阻你不要這樣做。

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