簡體   English   中英

MySQL和php中的獨特文本字段

[英]Unique text field in MySQL and php

我用鹽創造了一種鹽; MD5(蘭特(0,10000000)); (可能有更好的方法?)

似乎沒有可能在MYSQL中使文本字段唯一。 那么如何檢查鹽是否已用於以前的用戶?

或者我應該根據當前日期/時間生成鹽? 因為2個用戶不可能在完全相同的時間注冊正確嗎?

對於鹽,唯一性比長度和可預測性更重要。 你認為攻擊者有鹽。

通用唯一標識符(UUID)是最好的,並且有一些示例可以在php uniqueid()函數的doc頁面上生成通用唯一標識符。 UUID優於隨機字符串,因為它具有人類可讀性和固定長度,因此您可以將其存儲在varchar字段中並使用唯一索引來確保不會出現重復。

使用MD5散列時間是生成唯一值的常用方法,因為它具有固定長度並且是人類可讀的。 但是,生成固定長度的隨機字符串並將其自身編碼為十六進制更有意義。 哈希不是為了獨特而設計的,因為它們的設計不是可逆的。 使用散列函數可以保證沖突,但與SHA5相比,與MD5的沖突會更少。

鹽的長度實際上只是一個因素,因為鹽越長,它就越有可能是普遍獨特的。

MySQL的索引在文本字段上是長度限制的,它們不會像在char / varchar字段上那樣自動進入整個字段,因此沒有實際的方法在文本字段上使用“唯一”鍵。

但是如果你存儲由MySQL生成的哈希值,那么你不需要文本 - 結果是純文本的,所以只需使用一個固定長度的字段:

mysql> select length(md5('a')), length(sha1('a'));
+------------------+-------------------+
| length(md5('a')) | length(sha1('a')) |
+------------------+-------------------+
|               32 |                40 | 
+------------------+-------------------+

然后你可以對該字段應用唯一約束。

md5()是一個破碎的算法,永遠不應該觸及。

rand()略有損壞,因為它基於系統時鍾。

一個更好的方法是:

function generateRandomKey()
{
    return base_convert(uniqid(mt_rand(), true), 16, 36);
}

編輯:如果有更好的方法或我錯了,請告訴我你這樣做的方式。 我真的很感興趣,想知道我是不安全的。

您可以使用http://php.net/manual/en/function.uniqid.php之類的東西來生成UUID。 或者時間戳也是一個好的 - 甚至可能是時間戳和IP地址或類似的。

使用用戶標識和日期時間使用SHA1生成salt。

你通常不會生成鹽串。 所以當你第一次生成它們時,你應該做得很好。 更長和更隨機的字符串更好。

function generateSalt($length = null)
{
  if (!is_int($length) || ($length < 1)) $length = 250;
  do {
    $salt[] = chr(mt_rand(0, 255));
  } while (--$length);
  return implode('', $salt);
}

更新新密碼的查詢

update user set salt = :salt, password = sha1(concat(:password, :salt)) where id = :id limit 1;

您可以檢查密碼是否正確並同時獲取用戶數據。

select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;

暫無
暫無

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

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