簡體   English   中英

如何最好地存儲用戶信息和用戶登錄名和密碼

[英]How to best store user information and user login and password

我正在使用 Mysql 並且我假設最好將用戶的個人信息及其登錄名和密碼分離到兩個不同的表中,然后在兩者之間引用它們。

注意:為了澄清我的帖子,我了解保護密碼的技術(散列、鹽等)。 我只知道,如果我遵循我生活其他部分(投資、數據備份,甚至個人存儲)的做法,那么在最壞的情況下(包括表或火災),在表之間拆分信息可以保護您的附加數據。

不要存儲密碼。 如果它曾經坐在磁盤上,它可能會被盜。 相反,存儲密碼哈希。 使用正確的散列算法,如 bcrypt(包括鹽)。

編輯:OP 回應說他了解上述問題。

無需將密碼存儲在與登錄名不同的物理表中。 如果一個數據庫表遭到破壞,訪問同一數據庫中的另一個表並不是一個大的飛躍。

如果您非常關心安全性和深度安全性,您可能會考慮將用戶憑據存儲在與域數據完全獨立的數據存儲中。 通常采用的一種方法是將憑據存儲在 LDAP 目錄服務器中。 這也可能有助於您以后進行的任何單點登錄工作。

密碼應存儲為加密哈希,這是一種不可逆轉的操作,可防止讀取純文本。 在對用戶進行身份驗證時,密碼輸入會經過相同的散列過程並比較散列值。

避免使用快速且廉價的哈希,例如 MD5 或 SHA1; 目標是使攻擊者計算彩虹表(基於哈希沖突)變得昂貴; 快速哈希抵消了這一點。 對於身份驗證場景,使用昂貴的散列不是問題,因為它不會對散列的單次運行產生影響。

除了散列之外,還使用隨機生成的值對散列進行加鹽; 一個隨機數,然后將其存儲在數據庫中並在散列之前與數據連接。 這增加了計算碰撞時必須生成的可能組合的數量,從而增加了生成彩虹表的整體時間復雜度。

您的密碼哈希列可以是固定長度; 您的加密散列應該輸出可以編碼為固定長度的值,這對於所有散列都是相同的。

盡可能避免使用自己的密碼認證機制; 使用現有的解決方案,例如bcrypt

可以在http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-you-上找到有關如何處理密碼以及您需要關注的內容的出色解釋需要了解安全密碼方案

最后一點,請記住,如果攻擊者獲得了對您數據庫的訪問權限,那么您應該立即關注他們可能訪問的任何敏感或個人身份信息,以及他們可能造成的任何損害。

把它們放在同一張桌子上沒有錯。 事實上,它會更快,所以我強烈推薦它。 我不知道你為什么要分開它。

我會嘗試回答你最初的問題。 將所有內容放在一張桌子上很好,除非您只需要收集大量個人信息。 在這種情況下,將其拆分可能是有意義的。 該決定應根據您處理的個人信息量以及需要訪問的頻率來做出。

我會說大多數時候我會在一個表中做這樣的事情:

UserID, FirstName, LastName, Email, Password, TempPassword

但是......如果你收集的遠不止這些。 假設您正在收集電話、傳真、出生日期、傳記等。如果大部分信息很少被訪問,那么我可能會將它們放在自己的表中,並將其與一對一的關系聯系起來。 畢竟,表中的列越少,對該表的查詢就越快。 有時簡化最常訪問的表是有意義的。 盡管每當您確實需要訪問該個人信息時,JOIN 都會對性能造成影響,因此您必須考慮這一點。

編輯——你知道嗎,我只是想到了一些東西。 如果您在用戶名或電子郵件字段(無論您喜歡哪個)上創建索引,它幾乎可以完全消除在用戶表中創建如此多列的性能缺陷。 我這樣說是因為每當您登錄時,WHERE 子句實際上會非常快速地找到具有索引的用戶名,並且該表中有 100 列也無關緊要。 所以我改變了我的看法。 我會把它放在一張桌子上。 ;)

在任何一種情況下,由於安全性似乎是一個熱門話題,因此密碼應該是一個哈希值。 我建議使用 SHA1(或 SHA256,如果你真的很擔心的話)。 TempPassword 也應該使用散列,它僅用於忘記密碼功能。 顯然,使用散列,您無法解密並向用戶發送其原始密碼。 因此,您可以生成一個他們可以登錄的臨時密碼,然后在登錄后強制他們再次更改密碼。

所有這些數據都會與用戶保持 1:1 的關系嗎? 如果您可以預見允許用戶擁有多個地址、電話號碼等,那么您可能希望將個人信息分解到一個單獨的表中。

首先,聲明(希望)顯而易見,如果您可以以任何方式避免存儲用戶名和密碼,請這樣做; 這是一項重大責任,如果您的憑證存儲被破壞,它可能會為相同的用戶提供對許多其他地方的訪問(由於密碼共享)。

如果您必須存儲憑據:

  • 不要存儲可逆形式; 使用公認的算法(如 SHA-256)存儲哈希。 使用來自信譽良好、值得信賴的來源的加密軟件 - 不要試圖自行推出,您很可能會弄錯。
  • 對於每個憑證集,將鹽與散列數據一起存儲; 這用於“准備”散列,以便兩個相同的密碼不會產生相同的散列 - 因為這表明密碼是相同的。
  • 使用安全的隨機生成器。 弱隨機性是加密相關安全失敗的第一大原因,而不是密碼算法。

如果您必須存儲可逆憑證:

  • 選擇一個好的加密算法 - AES-256、3DES(過時)或公鑰密碼。 使用來自信譽良好、值得信賴的來源的加密軟件 - 不要試圖自行推出,您很可能會弄錯。
  • 對於每個憑證集,將鹽(未加密)與加密數據一起存儲; 這用於“准備”加密密碼,以便兩個相同的密碼不會產生相同的密文 - 因為這會泄露密碼是相同的。
  • 使用安全的隨機生成器。 弱隨機性是加密相關安全失敗的第一大原因,而不是密碼算法。
  • 將加密/解密密鑰與您的數據庫分開存儲在 O/S 安全文件中,只能由您的應用程序運行時配置文件訪問。 這樣,如果您的數據庫遭到破壞(例如通過 SQL 注入),您的密鑰不會自動受到攻擊,因為這通常需要訪問 HDD。 如果您的操作系統支持綁定到配置文件的文件加密,請使用它 - 它只會有所幫助並且它通常是透明的(例如 NTFS 加密)。
  • 如果可行,請存儲使用主密碼加密的密鑰本身。 這通常意味着您的應用程序。 將需要在啟動時輸入該密碼 - 在腳本的參數中提供它沒有好處,因為如果您的 HDD 被破壞,您必須假設可以查看密鑰文件和腳本。
  • 如果用戶名不是定位帳戶記錄所必需的,則加密用戶名和密碼。

以我個人的經驗,在這種情況下,將個人信息和登錄信息存儲在單個數據庫中是最佳做法。 原因是應該發生 SQL 注入,它僅限於(除非滲透者知道您的數據庫的內部布局)與數據相關的表,而不是提供對整個數據集團的訪問。

但是,請注意,這可能會以需要執行更多查詢為代價,從而影響性能。

您應該將它們存儲在同一張表中,並使用單向加密。 MD5 可以工作,但很弱,因此您可以考慮使用 SHA1 或其他方法。 將 2 個項目存儲在單獨的表中沒有任何好處。

暫無
暫無

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

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