MySQL 和 php 中独特的文本字段

发布于 2024-08-28 00:30:49 字数 151 浏览 9 评论 0原文

我使用以下方法创建了盐; md5(兰特(0,10000000)); (可能有更好的方法?)

似乎不可能在 MYSQL 中使文本字段唯一。那么如何检查盐是否已经被以前的用户使用过呢?

或者我应该根据当前日期/时间生成盐?因为 2 个用户不可能同时注册,对吗?

I've created a salt using; md5(rand(0,10000000)); (there is probably a better way?)

There doesn't seem to be possible to make a text field unique in MYSQL. So how do I check if the salt has already been used for a previous user?

Or should I generate the salt based on the current date/time? as it is impossible for 2 users to register at exactly the same time correct?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

他是夢罘是命 2024-09-04 00:30:49

对于盐来说,独特性比长度和可预测性更重要。你假设攻击者有盐。

通用唯一标识符 (UUID) 是最好的,并且有一些示例可以在 php uniqueid() 函数。 UUID 优于随机字符串,因为它是人类可读的且长度固定,因此您可以将其存储在 varchar 字段中并使用唯一索引来确保不重复。

使用 MD5 对时间进行哈希处理是生成唯一值的常用方法,因为它具有固定长度并且易于人类读取。然而,生成固定长度的随机字符串并自己将其编码为十六进制更有意义。哈希值的设计目的与其说是为了唯一性,不如说是为了不可逆而设计的。使用散列函数可以保证冲突,尽管 SHA1 的冲突比 MD5 少。

盐的长度实际上只是一个因素,因为盐越长,它就越有可能是普遍独特的。

For a salt, uniqueness is more important than length and predictability. You assume the attacker has the salt.

A universally unique identifier (UUID) would be best, and there are examples that generate universally unique identifiers on the doc page for the php uniqueid() function. A UUID has the advantage over a random string in that it's human readable and a fixed length, therefore you can store it in a varchar field and use a unique index to ensure there aren't ever duplicates.

Hashing the time with MD5 is a common method to generate unique values because it has a fixed length and is human readable. However, it makes more sense just to generate a fixed length random string and encode it into hex yourself. Hashes aren't designed for uniqueness so much as they're designed not to be reversible. Using a hashing function guarantees collisions, though there will be less collisions with SHA1 than MD5.

The length of the salt is really only a factor because the longer the salt, the more likely it is to be universally unique.

孤芳又自赏 2024-09-04 00:30:49

MySQL 的索引在文本字段上有长度限制,它们不会像在 char/varchar 字段上那样自动进入整个字段,因此没有实际的方法在文本字段上使用“唯一”键。

但是,如果您存储 MySQL 生成的哈希值,则不需要文本 - 结果是纯文本,因此只需使用固定长度的字符字段:

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

然后您可以对该字段应用唯一约束。

MySQL's indexes are length-limited on text fields, they don't go whole-field automatically like they do on char/varchar fields, so there's no practical way to use a 'unique' key on text fields.

But if you're storing hashes generated by MySQL, then you don't need text - the has results are plain-text, so just use a fixed-length char field:

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

and then you CAN apply a unique constraint to that field.

绻影浮沉 2024-09-04 00:30:49

md5() 是一个损坏的算法,永远不应该被触及。

rand() 有一点问题,因为它基于系统时钟。

更好的方法是:

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

编辑:如果有更好的方法或者我错了,请告诉我你的做法。我真的很感兴趣,并且想知道我是否缺乏安全感。

md5() is a broken algorithm and should never be touched.

rand() is slightly broken because it is based on the system clock.

A better method is:

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

Edit: If there is a better way or I'm wrong, please show me your way of doing it. I'm genuinely interested, and would like to know if I'm being insecure.

氛圍 2024-09-04 00:30:49

您可以使用类似 http://php.net/manual/en/function.uniqid .php 生成 UUID。或者时间戳也是一个不错的选择 - 甚至可以是时间戳和 IP 地址或类似的。

you can use something like http://php.net/manual/en/function.uniqid.php to generate a UUID. or the timestamp is also a good one - maybe even timestamp and ip address or similar.

花间憩 2024-09-04 00:30:49

使用用户 ID 生成 SHA1 的盐和日期时间。

Generate the salt with SHA1 using user id and datetime.

樱娆 2024-09-04 00:30:49

您通常不会经常生成盐字符串。所以当你第一次生成它们时,你应该做好工作。更长、更随机的字符串更好。

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;

You generally dont generate salt strings often. So when you first generate them, you should do a good job. Longer and more random strings are better.

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 query for new password

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

you can check if the password is correct and get the user data at the same time.

select * from user where id = :id and password = sha1(concat(:password, salt)) limit 1;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文