Создание сильных уникальных идентификаторов пользователя с PHP и MySQL - PullRequest
5 голосов
/ 06 августа 2009

Ahoy Stack Overflow! Это будет мой первый пост ...

Я пытаюсь идентифицировать пользователей с помощью соленого уникального открытого ключа.

  1. Алгоритм - Должен ли я использовать uniqid (), sha256, sha512, что-то еще? Все хеши будут засолены. NIST рекомендовал SHA256, но я предпочитаю слышать, что могут предложить другие.
  2. Поколение - Хэш (SALT + AUTO_INCREMENT_PK + CREATED_TIMESTAMP) достаточно? Больше энтропии?
    • Я бы использовал электронную почту, так как она уникальна для каждого пользователя, однако пользователь может изменить свой адрес электронной почты. Я также подумывал о том, чтобы сохранить signup_email, чтобы хэши не пересчитывались.
  3. MySQL Storage - В настоящее время наши идентификаторы являются INT (255) auto_increment первичными ключами. Как говорилось ранее, потенциально сотни миллионов ключей. В зависимости от алгоритма шифрования у меня должен быть идентификатор фиксированного размера. Могу ли я оставить INT (255) или использовать CHAR (n)?

---------------------- Thanks for reading :) -------------------------------

Ответы [ 5 ]

5 голосов
/ 06 августа 2009

Одно: если вы не доверяете пользователям их идентификаторы, отправка их через GET или POST не будет работать; все они видны мотивированным пользователям.


Я бы использовал SHA256, используя строку salt.counter.time, и использовал бы выходные данные для генерации GUID для фактического идентификатора. Это минимизирует вероятность столкновения.

Вам придется использовать CHAR для MySQL для хранения идентификаторов GUID.

См. Комментарии в http://us2.php.net/manual/en/function.uniqid.php для получения более подробной информации. AFAIK GUID не является частью ядра PHP, поэтому его нужно немного подделать.

3 голосов
/ 06 августа 2009

Если вы используете идентификатор пользователя как способ, позволяющий пользователю делать что-либо с вашим сервисом, если один пользователь «угадывает» идентификатор пользователя другого, он сможет делать все, что захочет, с его учетной записью.

У вас нет другого пароля или чего-либо подобного?


Ну, в таком случае вам нужно что-то совершенно уникальное, не так ли ;-)
(Надеюсь, я хорошо понял вопрос - но это может быть не так - извините, если это не так)

Что вы думаете об использовании Глобального уникального идентификатора (как, например, 61350955-9755-4AF3-8C19-6DBC42CA69E2) для ваших пользователей?
Для примера того, как они выглядят, взгляните на http://createguid.com/


В качестве идентификатора, этот GUID довольно длинный; это означает, что в вашей БД много байтов, если у вас миллионы пользователей ... Так что, вероятно, его не следует использовать в качестве какого-либо первичного / внешнего ключа.

Как насчет использования наименьшего возможного целого числа (которое соответствует количеству пользователей, которое у вас будет) в качестве первичного / внешнего ключа, так как оно будет дублироваться во многих местах приложения; и только "длинный идентификатор пользователя" хранится только один раз в вашей пользовательской таблице?

1 голос
/ 01 мая 2014

Я написал этот класс, который дает вам уникальный идентификатор из 24 символов, совместимый с полем идентификатора MongoDB (и использующий ту же логику для его создания). Может пригодиться в будущем.

<?php
/**
 * Generator for Mongo-like ObjectIds in pure PHP
 * Author: Mauricio Piacentini
 *
 * Inspired by https://github.com/justaprogrammer/ObjectId.js
 *
 */

class ObjectIdFactory
{   
    private $_datetime = null;
    private $_machine = null;
    private $_pid = null;
    private $_increment = null;

    public function __construct()
    {
        $this->_machine = str_pad(dechex(rand(0, 16777215)), 6, "0", STR_PAD_LEFT);
        $this->_pid = str_pad(dechex(rand(0, 32767)), 4, "0", STR_PAD_LEFT);
        $this->_increment = rand(0, 16777215);

        //We need a DateTime object to get timestamps, cache it
        $this->_datetime = new DateTime();
    }

    public function getNewId($forcedincrement = null)
    {
        if (is_null($forcedincrement)) {
            $this->_increment++;
            if ($this->_increment > 0xffffff) {
                $this->_increment = 0;
            }
        } else {
            $this->_increment = $forcedincrement;
        }
        $timestamp = $this->_datetime->getTimestamp();

        $timestamp_final = str_pad(dechex($timestamp), 8, "0", STR_PAD_LEFT);
        $increment_final = str_pad(dechex($this->_increment), 6, "0", STR_PAD_LEFT);
        return $timestamp_final . $this->_machine . $this->_pid . $increment_final;
    }

}

https://github.com/piacentini/ObjectId.php

0 голосов
/ 14 апреля 2010

Лично я использую md5 (uniqid (mt_rand (), true)), который создаст 32-символьный идентификатор (128-битное шестнадцатеричное число), который чрезвычайно сложно предсказать.

0 голосов
/ 06 августа 2009

Вы рассматривали возможность использования UUID ?

Быстрый поиск в Google дает несколько хороших ресурсов / ссылок.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...