Создание частных, уникальных, безопасных URL - PullRequest
13 голосов
/ 01 марта 2009

Я хотел бы сгенерировать безопасный тип URL-адреса одним щелчком, аналогичный приведенным ниже примерам. Я буду использовать PHP, но это не имеет значения, поскольку я просто пытаюсь понять основную концепцию. В некоторых ответах предлагается использовать GUID, но я не думаю, что это даст мне абсолютно уникальный, безопасный URL, как показано ниже.

#    Google Calendar
3qq6jlu04ptlhmb9fencsu5t2k
#    Private
3qq6jlu04ptlhmb9fencsu5t2k
#    Private 'token'
163a0afe7fkb1ba2acd04c11ef0eefe8
#    LogMeIn
#    1024 bit - 128 Character URL
72oxuj0fzefqo3fu04xjtvmd0adj2948rfh7g5by4forkwcy7t651z7hcb6kjjgqkxmvmfqpyrcfy15z1fto8ewcxstjc6avicag7d5qnoimsm19kb9kgi9i7v6z01d5

Я склоняюсь к этому 128-символьному стилю 1024-бит, поскольку он кажется очень безопасным. Я думаю, я мог бы сделать четыре хэша MD5 и объединить их, но действительно ли это эффективно?

У меня есть два конкретных намерения для URL, таких как этот, но я уверен, что есть другие, которые могут найти это полезным.

1) Мгновенный вход в систему ярлык / значок для пользователей

2) URL-адрес одноразового использования (ссылки для восстановления пароля)

Ответы [ 7 ]

9 голосов
/ 01 марта 2009

Попробуйте uniqid - и, возможно, объедините его с хэшем md5, как показано в примерах:

// no prefix
// works only in PHP 5 and later versions
$token = md5(uniqid());

// better, difficult to guess
$better_token = md5(uniqid(rand(), true));

Я должен отметить, однако, что никакие URL, сгенерированные таким образом (независимо от алгоритма хеширования), не будут «безопасными», просто очень трудно угадать.

9 голосов
/ 01 марта 2009

Обновление:

Для чего-то вроде одноразового URL я бы предложил предложенный GUID-esque подход. Убедитесь, что у вас короткий срок службы по ссылке.

Для мгновенного входа в систему не существует действительно безопасного способа иметь один URL.

Да, вы можете создать URL-адрес, который будет чертовски трудно угадать, но это не дает вам супер безопасности. Если вы хотите запомнить пользователей, почему бы не использовать зашифрованный куки-файл аутентификации?

В приведенном вами примере, Календарь Google не регистрирует вас по одному URL-адресу, вам нужно сначала пройти аутентификацию, прежде чем URL-адрес что-либо значит.

например. нажатие на календарь Google из моего Gmail дает мне:

https://www.google.com/calendar/render?tab=mc&gsessionid=-LTeHrnKoeAbDcVaN68NHA

Это не поможет вам получить доступ к моей учетной записи, пока вы не подтвердите свою личность.

Старый пост:

Вы можете сгенерировать GUID в PHP, используя com_create _guid и использовать его.

В Linux, я думаю, вы можете использовать uuid_create или этот код из здесь :

<?php
 function guid(){
 if (function_exists('com_create_guid')){
       return com_create_guid();
   }else{
       mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
       $charid = strtoupper(md5(uniqid(rand(), true)));
       $hyphen = chr(45);// "-"
       $uuid = chr(123)// "{"
               .substr($charid, 0, 8).$hyphen
               .substr($charid, 8, 4).$hyphen
               .substr($charid,12, 4).$hyphen
               .substr($charid,16, 4).$hyphen
               .substr($charid,20,12)
               .chr(125);// "}"
       return $uuid;
   }
}
echo guid();
?>
4 голосов
/ 01 марта 2009

Просто сгенерируйте GUID. Это важно, хотя это не последовательный GUID старого стиля.

Однако, похоже, что у php нет собственной функции генерации GUID. Функция com_create_guid, предложенная в другом ответе, по-видимому, доступна только в php при работе в Windows.

На странице руководства для пользователя есть вариант, предложенный для com_create_guid для не-Windows:

function guid(){
    if (function_exists('com_create_guid')){
        return com_create_guid();
    }else{
        mt_srand((double)microtime()*10000);//optional for php 4.2.0 and up.
        $charid = strtoupper(md5(uniqid(rand(), true)));
        $hyphen = chr(45);// "-"
        $uuid = chr(123)// "{"
                .substr($charid, 0, 8).$hyphen
                .substr($charid, 8, 4).$hyphen
                .substr($charid,12, 4).$hyphen
                .substr($charid,16, 4).$hyphen
                .substr($charid,20,12)
                .chr(125);// "}"
        return $uuid;
    }
}

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

3 голосов
/ 01 марта 2009

Идентификатор должен быть невозможно угадать, GUID уникален, но не так сложно угадать.

Вам нужен хороший генератор случайных чисел, в каждой библиотеке криптографии / шифрования есть хотя бы один, я не знаю PHP, поэтому не могу дать вам имя функции.

Затем вы должны решить, какой длины будет ваше случайное число, вы должны выбрать такую ​​длину, чтобы каждый, кто угадал число, получил неназначенное число - либо:

  1. Оцените количество уникальных URL-адресов, которые вам нужно сгенерировать, подсчитайте, сколько бит вам нужно для их представления, а затем удвойте количество бит (как минимум).

  2. Или возьмите наибольшее число, которое примут ваши пользователи

Теперь у вас есть «безопасный» номер, который вы можете просто преобразовать в десятичное, шестнадцатеричное или base64 и использовать эту строку.

2 голосов
/ 03 марта 2009

Я бы избежал этого для:

1) Мгновенный вход в систему ярлык / значок для пользователей

потому что эти URL можно кэшировать / регистрировать на прокси, веб-журналах, кеше браузера, закладках, электронной почте и т. Д.

1 голос
/ 03 марта 2009

Если вы хотите убедиться, что URL-адрес является уникальным и может использоваться только ограниченное количество раз:

  • Ведение небольшой базы данных с полями, такими как: RandomKey, InternalURL, Counter, TimeStamp

  • Создать случайное число из достаточно большого пула.
    Непоследовательных GUID должно быть достаточно

  • Сохраните его в своей базе данных как RandomKey вместе с фактическим внутренним URL-адресом или кодом ресурса, необходимым вашей системе для обработки этого URL-адреса, и отметкой времени.

  • Когда пользователь щелкает или вводит URL-адрес, сверяйте его с этой базой данных: если TimeStamp слишком старый или Counter слишком высокий, примите соответствующие меры (например, если вы хотите, чтобы этот URL-адрес быть доступным в течение ограниченного времени или определенного количества раз).
    В противном случае просто обработайте запрос с помощью InternalURL и отправьте его результат обратно пользователю.

  • Когда URL-адрес использовался или достиг максимального значения счетчика, просто удалите его из базы данных, чтобы он больше не мог использоваться.

Это замечательно, если дать вам одноразовые URL, которые практически невозможно угадать.

Конечно, вы также должны внедрить некоторые проверки безопасности, чтобы ограничить скорость, с которой люди могут пытаться получить доступ к неверному URL.

1 голос
/ 02 марта 2009

Для обрезки дополнительных фигурных скобок

$ guid = strtolower (trim (com_create_guid (), "{}")); (PHP 5 или более поздняя версия)

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