|
|
|
|
|
для: alexhoppus
(19.08.2009 в 23:47)
| | Извините, что не прочитал это всё (я бы здох), но есть виды HTTP-авторизации. Два основных вида - Basic и Digest. Здесь можно прочитать про защищённый метод Digest: http://xakep.ru/post/27203/default.asp Там есть и готовый код. Вот улучшенный код:
====== security.php ======
<?php
############################################################# #### ####
#### == Digest Authentication == #### # # ####### ## # ####### ######
#### Made by: ][akep Online (xakep.ru) #### # # #_____# ##__ # ##__ #____#
#### Modernization: ~AquaZ~ #### # # #-----# ##--# ##-- #
############################################################# #### #### # # ## ## ###### #
# | -- Changes -- |
# | All data saving to 1 (one) file |
# | in serialized and compressed |
# | (deflated) array. |
# | |
# | Data that living more than |
# | 30 min. automatically dies |
# | |
# | Script optimized |
# | |
# | Script can get IP |
# | from HTTP_X_FORWARDED_FOR |
# |_________________________________|
function authorize($realm,$file,$userlist,$target){
$nonce = ip2long(getip()).time();
$headers = apache_request_headers();
$auth_success = false;
$stale = "false";
if (isset($headers['Authorization'])){
$authorization = $headers['Authorization'];
preg_match_all('/(,|\s|^)(\w+)=("([^"]*)"|([\w\d]*))(,|$)/',$authorization,$matches,PREG_SET_ORDER);
for ($i = 0; $i < count($matches); $i++){
$match = $matches[$i];
$auth_params[$match[2]] = $match[4] . $match[5];
}
$a1 = $auth_params['username'] . ':' . $auth_params['realm'] . ':' . $userlist[$auth_params['username']];
$a2 = $_SERVER['REQUEST_METHOD'] . ':' . $_SERVER['REQUEST_URI'];
$resp = md5(md5($a1) . ':' . $auth_params['nonce'] . ':' . md5($a2));
if ($resp == $auth_params['response']){
$arr = unserialize(gzinflate(file_get_contents($file)));
if (long2ip($arr[$auth_params['nonce']][0]) == $_SERVER['REMOTE_ADDR']){
unset($arr[$auth_params['nonce']]);
file_put_contents($file,gzdeflate(serialize($arr)));
$auth_success = true; // Аутентификация пройдена
} else {
$stale = "true";
}
}
}
if (!$auth_success) die;
}
##############################################################
#### == Simple IP getter == ####
#### Made by: ~AquaZ~ ####
##############################################################
function getip(){
$ip = getenv('HTTP_X_FORWARDED_FOR');
if (!$ip || ($ip == 'undefined') || empty($ip)) $ip = $_SERVER['REMOTE_ADDR'];
return $ip;
}
##############################################################
#### == Digest Authentication rubbish killer == ####
#### Made by: ~AquaZ~ ####
##############################################################
Mycop_Hax($file);
function Mycop_Hax($file,$maxlive = 1800){
$f = unserialize(gzinflate(file_get_contents($file)));
if (is_array($f)){
foreach($f as $key => $val){
if ($val[1] < time() - $maxlive) unset($f[$key]);
}
unlink($file);
file_put_contents($file,gzdeflate(serialize($f)));
}
}
?>
|
==== Начало защищённого файла (до вывода информации; если security.php лежит в inc/) ====
<?php require 'inc/security.php'; authorize('Название зоны','inc/temp.tmp',$userlist);
|
Первый параметр - имя защищённой зоны. Второй - файл с мусором, может быть любой. Самоочищается. Третий - ассоциативный массив
$userlist['логин'] = 'пароль'
|
| |
|
|
|
|
|
|
|
для: psychomc
(14.08.2009 в 14:32)
| | От подделки (если кто-то узнает SID кого-то и зайдет под ним) | |
|
|
|
|
|
|
|
для: Рома
(14.08.2009 в 20:29)
| | Да нет, почему же.
Если Вы посмотрите методику аутентификации в IMAP (метод DIGEST-MD5 в SMTP ) , то увидите, что авторы также ориентировались на предварительное хеширование пароля на стороне клиента.
Но этот первый фрагмент, который при авторизации играет роль челенджа (исследующей строки сервера) в процессе генерации пароля поручать серверу какой смысл?
Сам фрагмент, кстати, полезен. Иначе короткие пароли будут подбираться через rainbow-tables. | |
|
|
|
|
|
|
|
для: Trianon
(14.08.2009 в 20:13)
| | >Какую роль играет факт генерации элемента скрытое_поле_1 на серверной стороне?
Чтоб усложнить расшифровку пароля. Хотя мне самому это не очень нравиться, как то не гармонично.
Скажите, я хренью занимаюсь? Просто я нигде еще не видел, чтобы при регистрации хешировался пароль на клиенте. | |
|
|
|
|
|
|
|
для: Рома
(14.08.2009 в 13:32)
| | Какую роль играет факт генерации элемента скрытое_поле_1 на серверной стороне?
У меня просьба, описывая диалог в протоколе, пишите действия каждой из сторон на отдельной строке. Иначе протокол очень тяжело читать. | |
|
|
|
|
|
|
|
для: Саня
(14.08.2009 в 13:55)
| | . | |
|
|
|
|
|
|
|
для: Alexhoppus
(12.08.2009 в 13:57)
| | это от кражи сессии? | |
|
|
|
|
|
|
|
для: Рома
(14.08.2009 в 13:32)
| | И что с того? В базу-то всё равно попадёт хеш, а не пароль. И при логине можно будет отключить js и в поле с паролем вписать этот хеш. Вы всего лишь перенесли реализацию часть логики на клиента. | |
|
|
|
|
|
|
|
для: Trianon
(14.08.2009 в 00:58)
| | Моя вчерашняя теория не будет работать стабильно, иначе уже давно была бы реализована. Если при "частично защищенной авторизации с помощью JS" можно авторизовать пользователя что с включенным JS, что с выключенным, то "частично защищенная регистрация с помощью JS" при отключении этого JS рушится, точнее потом невозможно будет авторизоваться. Разве что предупреждать об этом пользователя.
А выглядит это так.
Клиент просит страницу регистрации, сервер генерит случайную строку, сохраняет ее в сессию и отправляет вместе с формой скрытым_полем_1. Перед отправкой данных клиент с помощью JS делает MD5(скрытое_поле_1 + MD5(password)). Сервер сохраняет логин, скрытое_поле_1 и полученный хэш.
При авторизации клиент просит страницу, сервер генерирует случайную строку, сохраняет ее в сессию и отправляет вместе с формой скрытым_полем_2. После ввода логина, клиет с помощью ajax подключается к серверу, по логину достает из базы сохраненное скрытое_поле_1 и подгружает его в форму. После нажатия submit клиент осуществляет MD5(скрытое_поле_2 + MD5(скрытое_поле_1 + MD5(password))).
Плюс: Пароль всегда передается только хэшем.
Минус: Не работает при отключенном JS. И вообще заморочка.
Остальные ситуации думаю можно урегулировать и подкорректировать.
Можно пойти другим путем, и при регистрации отправлять на сервер просто MD5(password). Никаких заморочек, результат тот же - пароль всегда передается только хэшем. | |
|
|
|
|
|
|
|
для: Рома
(14.08.2009 в 01:02)
| | Не вопрос :) | |
|
|
|
|