簡體   English   中英

MySQL區分大小寫(否則,如何在MySQL中正確存儲密碼)

[英]MySQL Case Sensitivity (or otherwise, how to store passwords correctly in MySQL)

原因:

我有一張桌子,所有的列都適當地Collatedutf8mb4_unicode_ci

CREATE TABLE IF NOT EXISTS `users` (
  `user_id` int(8) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) NOT NULL,
  `pass_word` varchar(512) NOT NULL ,
  ...etc etc...
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `email_addr` (`email_addr`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=989 ;

...包括存儲密碼哈希(從password_hash生成)的列,例如$2y$14$tFpExwd2TXm43Bd20P4nkMbL1XKxwF.VCpL.FXeVRaUO3FFxGJ4Di

但是 ,我發現由於該列的大小寫不敏感, $2y$14$tFpExwd2tXm43Bd20P4NKmbL1XKxwF.VCpL.FxEVRaUO3FFxGJ4DI的哈希仍將允許訪問。

這意味着通過以不區分大小寫的方式存儲數據,有可能發生數百次沖突。 不好。


問題:

現在,有沒有一種方法可以強迫MySQL在進行比較時將pass_word列視為區分大小寫的列。 我想避免不得不編輯每次出現的PHP / SQL查詢,而是默認情況下只是將數據庫表列設置為以區分大小寫的方式進行比較。

utf8mb4字符集沒有給我任何_cs選項,唯一的非_ci選項似乎是utf8mb4_bin

如此簡單的問題:

  • MySQL上的UTF8mb4_bin字符集和排序UTF8mb4_bin是否敏感地區分標准比較? [是]
  • 劑量UTF8mb4_bin適合我要做什么。 我應該使用另一套嗎?如果是,為什么?
  • password_hash輸出存儲在MySQL utf8mb4_bin列中是否有任何問題?
  • 這種方法是否方便地回避了編輯每個登錄查詢的查詢SQL的需要? 我可以更改列類型然后繼續嗎?

編輯

正如nj_所詳述的,這是一個愚蠢的問題,根本不是問題,因為登錄時從不直接編輯pass_word的值。

如果您真的擔心在62 ^ 55地址空間中可能發生2 ^ 55沖突,則可以將列類型更改為BLOB,這始終區分大小寫。

CREATE TABLE IF NOT EXISTS `users` (
  `user_id` int(8) NOT NULL AUTO_INCREMENT,
  `username` varchar(100) NOT NULL,
  `pass_word` BLOB NOT NULL ,
  ...etc etc...
  PRIMARY KEY (`user_id`),
  UNIQUE KEY `email_addr` (`email_addr`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=989 ;

例:

INSERT INTO `users` (..., `pass_word`) VALUES (..., 'AbC');

SELECT * FROM `users` WHERE `pass_word` = 'AbC' LIMIT 0,1000; -> 1擊

SELECT * FROM `users` WHERE `pass_word` = 'abc' LIMIT 0,1000; -> 0次

在這種情況下,區分大小寫是沒有問題的,因為無論如何您都無法直接使用SQL驗證密碼。 無法在數據庫中搜索正確加鹽的密碼哈希。 僅按用戶名搜索,然后從數據庫中提取存儲的哈希:

$sql= 'SELECT * FROM users WHERE username = ?';
$db->prepare($sql);
$db->bind_param('s', $_POST['username']);

然后,您可以從該行中提取哈希值,並使用password_verify()函數將輸入的密碼與找到的哈希值進行比較:

// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

暫無
暫無

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

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