|
|
|
|
|
для: Trianon
(22.01.2009 в 16:21)
| | Почему? я проверял, разница есть и вполне существенная. Две последних цифры очень даже прилично скачут. | |
|
|
|
|
|
|
|
для: Николай2357
(22.01.2009 в 13:48)
| | >Раз уж муссировался вопрос о функции microtime(),
В аспекте разового вызова, но никак не повторения в цикле.
Понятно, что никакой случайной составляющей повторные вызовы не привнесут. | |
|
|
|
|
|
|
|
для: serjinio
(22.01.2009 в 01:58)
| | Ну вот, я добрался до компа.
Ваши основные ошибки:
1. Вы пытаетесь усложнить жизнь хакеру, спрятав за "непроницаемую" стену пароль юзера. Скажите - зачем? Ведь суть задачи дать возможность активировать запись только тому, кто знает ключ к активации, а пароль юзер знает лучше Вас, и в ответном письме он ему совсем не нужен. Чего нельзя сказать о злоумышленнике, перехватившем это письмо каким нибудь хитрым трояном. Задача заключается в двух главных моментах.
а) Исключить возможность активации записи методом подбора или расшифровки кода.
б) Идентифицировать пользователя по этому самому коду.
По первому пункту. Есть два пути - генерация случайного кода, что оказалось не так уж и просто, и ограничение числа попыток активации. Я склоняюсь ко второму, но если хотите первый - пожалуйста.
Что бы потерялся смысл расшифровки, нужно сгенерировать действительно случайную строку, которую нельзя дешифровать, вычислив некоторые параметры. Лучшим способом, как выяснилось, является генерацуия на основе не псевдослучайных параметров, а на действительно случайных. Раз уж муссировался вопрос о функции microtime(), то вот так можно сгенерировать случайную строку, похожую на хэш:
<?
// Массив можно заполнить статически, просто жалко места и лень.
$arr_num = range("0","9");
$arr_let = range("a","f");
$arr = array_merge($arr_num,$arr_let);
$arr = array_merge($arr,$arr_let);
$arr = array_merge($arr,$arr_num);
$arr = array_merge($arr,$arr_let);
$arr = array_merge($arr,$arr_let);
$arr = array_merge($arr,$arr_let);
$arr = array_merge($arr,$arr);
$rand = microtime(1);
for($i = 0; $i < 32; $i++)
{
$key .= $arr[(round(($rand * 1000 - floor($rand * 1000)),2) * 100 )];
$rand = microtime(1);
}
echo $key;
| Но эта процедура не даст гарантии уникального кода, а для чистоты эксперимента он должен быть уникальным. По этому нужен параметр, который не повторится ни при каких обстоятельствах. Идеальным является id записи. А так как смысла расшифровки кода нет, то можно процедуру упростить.
<?
mysql_query("INSERT INTO `users`..."
$id = mysql_insert_id();
$arr_num = range("0","9");
$arr_let = range("a","z");
$arr = array_merge($arr_num,$arr_let);
$arr = array_merge($arr,$arr);
$arr = array_merge($arr,$arr_let);
$arr[] = "a";
$rand = microtime(1);
for($i = 0; $i < 10; $i++)
{
$key .= $arr[(round(($rand * 1000 - floor($rand * 1000)),2) * 100 )];
$rand = microtime(1);
}
$r_key= md5($id.$key);
mysql_query("UPDATE....... (...`r_key`, ............VALUES ( ...'$r_key',....')",
// Отправляем письмо
| В результате мы имеем уникальный и не поддающийся подбору хэш, по которому и можно идентифицировать юзера:
<?
$key = isset($_GET['key']):$_GET['key']?null;
if($key)
{
$key = (get_magic_quotes_gpc())?mysql_escape_string(stripslashes($key)):mysql_escape_string($key);
$SQL=mysql_query("SELECT `u_log`,`u_salt`,`u_pass`,`u_activat`
FROM `users`
WHERE `r_key`='$key' ",$db);
if (mysql_num_rows($SQL) > 0 )
{
$rw = mysql_fetch_assoc($SQL);
echo '<br>Есть такой юзер..'.$rw['u_log'].' ! делаем дальше проверки..
был ли уже активирован данный логин ..
не истёкли срок активации ....
если все ОК пишем в базу..
если нет удаляем его из базы и пусть идет по новой... !<br>';
}
| Вот и вся недолга. Только намудрил я маленько, можно наверное оптимизировать, просто мне ближе вариант с попытками. | |
|
|
|
|
|
|
|
для: serjinio
(22.01.2009 в 01:58)
| | >какие могут быть подводные камни...
Вернее было бы сказать - где тут вода, и есть ли она под камнями....
Если завтра будет время, я перепишу Ваш код, это проще будет, чем поэтапно объяснять. | |
|
|
|
|
|
|
|
для: serjinio
(21.01.2009 в 11:31)
| | Ну вот добрался до комьютера...
вариант активации одной ссылкой с одним параметром....
<?
/* Соль */
// воспользовался кодом Николая....
$r_key= substr(str_shuffle('abcdef0123456789'),11);// Создадим код "Соли" того-же вида, что и md5-хэш
/* В базе данных у нас будет храниться md5-хеш пароля */
$p =$_POST['pass'];
$md_p = md5(sha1($p));
mysql_query("INSERT INTO `users` (`u_log`,`u_pass`,`u_salt`, ............VALUES ( '$r_key',......'$md_p')",$db);
if ($new == 'true')
{
/* Составляем "Ключ" для активации */
$u_key = $md_p.$r_key;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Получаем ссылку на активацию
// .php?key='.$u_key.'" target="_blank">АКТИВИРОВАТЬ !</a>
// .php?key=c72f5359811af711f29b1fac7150042fed3 72
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Активируем.....
if (isset($_GET['key']))
{
/* Устанавливаем соединение с БД */
include_once ('../config.php');//сonnect BD
// Вырезаем соль...
$salt= substr(trim(htmlspecialchars($_GET['key'],ENT_QUOTES,'UTF-8')),32); // ed372
/* Формируем SQL-запрос */
$SQL=mysql_query("SELECT `u_log`,`u_salt`,`u_pass`,`u_activat`
FROM `users`
WHERE `u_salt`='$salt' AND `u_activat` = 0 ",$db);
if (mysql_num_rows($SQL) > 0 )
{
$rw = mysql_fetch_assoc($SQL);
echo '<br>Есть такой юзер..'.$rw['u_log'].' ! делаем дальше проверки..
был ли уже активирован данный логин ..
не истёкли срок активации ....
если все ОК пишем в базу..
если нет удаляем его из базы и пусть идет по новой... !<br>';
}
|
Длину соли можно сделать любую,вставить ее можно и в начало и в конец и хоть в середину .
она все равно выглядит как и код md5.....как фантазия работает.....
вроде работает..утром еще нормально протестирую...
..самое главное идея.. что скажите ..какие могут быть подводные камни... | |
|
|
|
|
|
|
|
для: Николай2357
(21.01.2009 в 18:19)
| | Вы не учитываете время на прохождение запроса от клиента на сервер.
не факт, что оно будет таким стабильным
Но в принципе, Вы правы.
Почему я и написал, что сильно много случайных бит из этого источника не выжать. | |
|
|
|
|
|
|
|
для: Trianon
(21.01.2009 в 17:58)
| | Каюсь, грешен... Единичку забыл. Но результат не многим лучше С рефрешем - минута работы - 24 совпадения. | |
|
|
|
|
|
|
|
для: Николай2357
(21.01.2009 в 17:50)
| | дату-время в Unix-формате, уже предлагавшуюся здесь альтернативой, вполне можно и спрогнозировать.
Что до microtime() - задача понятна, но всё ж сперва может поглядеть, что возвращает эта функция, а потом уже писать код? | |
|
|
|
|
|
|
|
для: BinLaden
(21.01.2009 в 16:34)
| | Форум сегодня веселит не на шутку... | |
|
|
|
|
|
|
|
для: BinLaden
(21.01.2009 в 16:34)
| | - | |
|
|
|
|