За последние 24 часа нас посетили 22898 программистов и 1052 робота. Сейчас ищут 639 программистов ...

Класс по дигест (Digest) Авторизации

Тема в разделе "Решения, алгоритмы", создана пользователем nimistar, 1 июл 2007.

  1. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    теория здесь

    сам класс:

    примечание:

    есть два варианта или хранить пароль в открытом виде, или
    в поле пароля, хранить уже зашифрованное значение

    Код (Text):
    1. H(A1)
    , что есть
    Код (Text):
    1. md5(userName:Realm:password)
    правда при этом себя жестко привязываешься к Realm - что неудобно!

    я использую шифрованный вариант!



    PHP:
    1.  
    2. <?php
    3. class Digest{
    4.   private $autorequest=false;  // Указатель на автоматический запрос авторизации при отсутвующей авторизации
    5.   public $REALM=''; // Название защищаемой области
    6.   public $DBinfo=array('table'=>'users','user_field'=>'login','passw_field'=>'digest_a1','id_field'=>'id');//параметры подключения к базе данных
    7.   public $USERNAME = ''; // здесь формируется имя после регистрации
    8.   public $UID = ''; // здесь формируется индетификатор учетной записи после регистрации
    9.   public $ERROR=''; // Лог ошибок
    10.   private $session_name='SID'; // идентификатор сессии
    11.  
    12.   private $nc=0; //подсчет количества раз использования параметра нонсе без изменений
    13.   //(работает хреново .... неразобрался как он начисляется ... у меня в некоторых браузерах он скакал: 1-15-18-34-35-43.... то есть хз как)
    14.  
    15.   function Digest($autorequest,$REALM_,$DBinfo_){
    16.     if(session_id()===''){session_name($this->session_name);session_start();}
    17.     $this->REALM=$REALM_;
    18.     $this->DBinfo=$DBinfo_;
    19.     $this->autorequest=$autorequest;
    20.   }
    21.  
    22.   function auth_success(){
    23.     GLOBAL $_SERVER,$_SESSION;
    24.     $headers = apache_request_headers();
    25.     if (isset($headers['Authorization'])&&isset($_SESSION['nonce'])&&($_SESSION['hash']===$this->GetHash())){
    26.         $headers = $headers['Authorization'];
    27.         preg_match_all('/(,|\s|^)(\w+)=("([^"]*)"|([\w\d]*))(,|$)/',$headers, $matches, PREG_SET_ORDER);
    28.         $auth_params = Array();
    29.         for ($i = 0; $i < count($matches); $i++){
    30.             $auth_params[$matches[$i][2]] = $matches[$i][4] . $matches[$i][5];
    31.         }
    32.         if(mysql_ping()){
    33.             $SQL='SELECT * FROM '.$this->DBinfo['table'].' WHERE '.$this->DBinfo['user_field'].'="'.htmlspecialchars($auth_params['username']).'"';
    34.             $SQLresult=mysql_query($SQL) or $this->ERROR="Неверный запрос:$SQL<br>ERROR(".mysql_errno()."):<i>".mysql_error()."</i>";
    35.             if(empty($this->ERROR)){
    36.                 $REC=mysql_fetch_assoc($SQLresult);
    37.                 $this->USERNAME=$REC[$this->DBinfo['user_field']];$this->UID=$REC[$this->DBinfo['id_field']];
    38.                 $this->nc=base_convert($auth_params['nc'], 16, 10);
    39.                 $response = md5($REC[$this->DBinfo['passw_field']].':'.$_SESSION['nonce'].':'.$auth_params['nc'].':'.$auth_params['cnonce'].':auth:'.md5($_SERVER['REQUEST_METHOD'].':'.$auth_params['uri']));
    40.                 if ($response == $auth_params['response'])Return true;
    41.             }
    42.         }else{$this->ERROR='don\'t have connect to mysql';}
    43.     }else{
    44.       if (isset($headers['Authorization']))$this->ERROR='don\'t have response about authorization'."\r\n";
    45.       if (isset($_SESSION['nonce']))$this->ERROR='don\'t have nonce in session data'."\r\n";
    46.       if ($_SESSION['hash']===$this->GetHash())$this->ERROR='Bad hash in resived information'."\r\n";
    47.       unset($_SESSION['nonce']);unset($_SESSION['hash']);session_regenerate_id($this->session_name);
    48.     }
    49.     if($this->autorequest)$this->Init();
    50.     Return false;
    51.   }
    52.  
    53.   function Init(){
    54.         global $_SESSION;
    55.         mt_srand(time()+(double)microtime()*10000000);
    56.         $nonce = md5($_SERVER['REMOTE_ADDR'] . ':' . time() . ':'.mt_rand());
    57.         $_SESSION['nonce']=$nonce;
    58.         $_SESSION['hash']=$this->GetHash();
    59.         Header ("HTTP/1.1 401 Not Authorized");
    60.         Header ('WWW-Authenticate: Digest realm="'.$this->REALM.'", qop="auth", nonce="'.$nonce.'"');
    61.       print "<html><head><title>Digest auth </title></head><body>";
    62.         print "<b>You must authenticate with Digest method</b>";
    63.         print "</body></html>";
    64.   }
    65.  
    66.   function LogOut(){
    67.     global $_SESSION;
    68.     unset($_SESSION['nonce']);
    69.     header ("Location: [url=http://]http://[/url]".$_SERVER['SERVER_NAME'].$_SERVER['SCRIPT_NAME']);
    70.     exit();
    71.   }
    72.  
    73.   function GetHash(){
    74.      global $_SERVER;
    75.      return md5(md5($_SERVER['HTTP_USER_AGENT']).':'.md5($_SERVER['REMOTE_ADDR']).':'.md5($_SERVER['HTTP_HOST']));
    76.    
    77.   }
    78. }
    79. ?>

    как с ним работать:
    пример первый - без автоматической регистрации:
    PHP:
    1. <?php
    2. require_once("class/class.digest.php");
    3. $AUTH = new Digest(false,'Content Moderation',array('table'=>'cm_priv.users','user_field'=>'login','passw_field'=>'digest_a1','id_field'=>'id'));
    4. $ThisState=$AUTH->auth_success();
    5. if(htmlspecialchars(@$_GET['login'])==='in' && !$ThisState)$AUTH->Init();
    6. if(htmlspecialchars(@$_GET['login'])==='out' && $ThisState)$AUTH->LogOut();
    7. if($ThisState){
    8.   $REG='Здраствуйте, '.$AUTH->USERNAME.'<br><a href="?login=out">Выход</a>';
    9. }else{
    10.   $REG='<br><a href="?login=in">Вход</a>';
    11. }
    12. echo $REG;
    13. ?>
    пример второй -с автоматическим запросом авторизации:
    PHP:
    1. <?php
    2. require_once("class/class.digest.php");
    3. $AUTH = new Digest(true,'Content Moderation',array('table'=>'cm_priv.users','user_field'=>'login','passw_field'=>'digest_a1','id_field'=>'id'));
    4. if(!$AUTH->auth_success()){echo '<b> Необходима авторизация на сервере: </b>('.$AUTH->ERROR.')';exit();}
    5. ?>
    6.  
    Ожидаю любые замечания, от "нафиг это вообще", до " запитая не там".[/i]
     
  2. Anonymous

    Anonymous Guest

    1. Дафика букаф.
    2.Теория где?
     
  3. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    да, чтение rfc, чтобы понять, что же пытался реализовать автор - увлекательнейшее занятие :)
    ответь на два вопроса:
    1. что ты пытался сделать?
    2. почему бы не сделать это проще?
    насколько я понял - ты реализовал это гадкое выпрыгивающее окно с требованием ввести лог/пасс... в очень извращённой форме и жёсткой привязкой к субд...
     
  4. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    1. наоборот ... мало :) попробуй форум перечесть - вот это много ...а тут ....
    2.теория в мануале :) сами же отсылаете ...


    угу! тоже так считаю .... хотя теорию Дигеста я думаю тут уже все наизусть знают ...


    гм ... читай сабжект- дигест авторизацию

    есть варианты ??? приведи сравним.... или это ты про конфиг апача ????
    дык его минусы написанны даже в ркаводстве по настройке апача!
    есть варианты сквозь сессию только ... но там то пароль открыто передается!

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

    смысл класса - хранение зверей в базе, реализация плюсов дигест и сессии, с попыткой сгладить минусы того и другого способа!
     
  5. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    что есть "дигест" и в чём его преимущества перед обычным решением?
     
  6. vb

    vb Активный пользователь

    С нами с:
    6 июн 2006
    Сообщения:
    911
    Симпатии:
    0
    Адрес:
    Saint-Petersburg
  7. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    vb - мне непонятен ваш взгляд! причем тут изварщение ???
    использую всюду в замен формочек на страничке :)


    дигест авторизация обладает одним емким приемуществом пред всеми остальными типами ... пароль в зашифрованном виде!

    но есть мощный недостаток: невозможность разлогинется (который данным классом и решается)

    если честно то в базе хранить зверей- так как это предлагал мне сам апач - мне непонравилось! да ещё лишний коннект к базе!

    здесь, и хранение зверей в базе в удобном тебе виде .... практически без привязки к полям... и сессионная зависимость ... и разлогинивание, причем если в апачевском модуле невозможно осуществить доступ к контенту и в авторизованном виде и в не авторизованном виде одновременно, то данная возможность в классе есть!
     
  8. Anonymous

    Anonymous Guest

    Если честно — на троечку... с натягом... ясной мысли не вижу.
     
  9. vb

    vb Активный пользователь

    С нами с:
    6 июн 2006
    Сообщения:
    911
    Симпатии:
    0
    Адрес:
    Saint-Petersburg
    Позиция проста как три копейки, не надо страдать параноей :).
    В подавляющем большинстве случаев достаточно обычной авторизации - при помощи разовой передачи пароля и дальнейшего поддержания сессии БЕЗ ПАРОЛЯ.
    Если необходимо обеспечить секюрность соединения я куплю сертификат SSL и не буду знать таких проблем.

    Хотя для решений эконом класса данный способ может оказаться полезным. Но если бы информация передаваемая между клиентом и сервером была бы действительно важна - как говорил использую SSL. Все равно при передачи CVC Code кредитки данный способ как я понимаю не подходит. Или я не правильно понимаю?
     
  10. Anonymous

    Anonymous Guest

    Хочется внести яснось, да, данное решение, выполняемое средствами Апача, НИЧЕМ не особо не защищенней, чем собственная авторизация.
     
  11. Davil

    Davil Guest

    Если без SSL - просто почаще меняй sid и будет тебе безопасность.
    Если делаешь сайт для пентагона - пользуй ssl...
     
  12. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    "не надо страдать параноей " - да ладно ... это полезно!
    вообщем класс наверное действительно для параноиков нежелающих связываться с ССЛ!

    vb - ССЛ ... хорошо ... но не выгодно .... ведь HTTPS это другой протокол по отношению к к простому HTTP... если необходимо предать только пароль зашифрованным то использовать HTTPS просто нерентабельно!
    "не надо страдать параноей " - да ладно ... это полезно!
    естественно что при передачи данных кредиток этот способ банально неуместен ... (ведь все нацеленно на шифрование ПАРОЛЯ, и никаких других данных!)


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

    А вот где столкнулись с необходимостью шифрования именно пароля ... так это в интернет магазине нацеленном на БОЛЬШОЕ количество пользователей .... и где потеря пароля связанна с прямыми денежными потерями (магазин где деньги хранятся на счете пользователя), вот тогда была поставленна задача шифрования пароля (тесты с ССЛ показали что нам необходим кластер из 5 машин с системой распределения нагрузок - на том месте где одна машина легко держала обычный HTTP, да ещё заказчики воспротивились смене протокола на лету при областях подверженным атакам - неудобно для пользователей), тогда я стал разрабатывать этот класс ... но как временное решение мы шифровали пароль при помощи джавыСкрипта..... теперь полностью разобравшись с дигестом я написал этот класс, но та работа уже ушла ... потому просто решил поделиться с вами ... вдруг понадобится!


    З.Ы. : ни в коем случае я не претендую на истинность в последней инстанци ... но согласитесь что , наличие выбора в методах шифрования и обмена данных есть плюс, а не минус!

    а вот что решает данный клас:
    1. шифрованный пароль! :)
    2. невозможность передачи урла между пользователями (даже когда совпадает агент, айпи, сид)
    3. независимость от джавыСкрипта - для шифрования.
    4. нет необходимости писать форму логинизации и реализовывать проверку входных данных (дигест есть дигест и реализация его в одном классе больше никогда не потребует его перебора под специфические условия).
    5. возможность разорвать сессию – «разлогиниться» несмотря на Дигест (в котором это непредусмотренно)


    Горбунов Олег - в твоей фразе я тоже - "ясной мысли не вижу" - что на троечку ??? реализация или причина ??
     
  13. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    на работе очень долго спорили и методах и о причинах ... смешно смотрится что и сейчас этот же разговор как бы повторяется ... с теми же самими доводами!
     
  14. vb

    vb Активный пользователь

    С нами с:
    6 июн 2006
    Сообщения:
    911
    Симпатии:
    0
    Адрес:
    Saint-Petersburg
    Этим постом следовало начинать ветку :)
    Пример с магазинами хороший, реализацию с ява-скриптом тоже встречал :)
    Вечером - если не забуду потестю ваш класс :)
     
  15. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    если честно ... то как раз и нехотел привязываться к вопросу зачем! тут скорее показывал опыт работы с дигестом!
    а класс показывает эту работу ... ну и + пытался убрать баги дегеста!

    например в вышепреведенной тобой статье есть фраза - "Nonce позволяет не передавать пароль в открытом виде, и только. Сервер не запоминает все выданные nonce и не следит за ними." за этим кроется АФИГЕННЫЙ баг .... вот перехватили мы страничку с заголовком... и хоть Nonce уже на серваке удален (как удален ? он же там и нехранится)

    так вот получается что опять послав перехваченный заголовок мы опять получаем защищенный контент .... а в моем классе и эта проблема решена!

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

    Anonymous Guest

    ЧЕ-ПУ-ХА!
    Приложению вообще глубоко пофиг, оно не знает, по http или https оно работает.
    то они 100% знакомы, и ничего не мешает им просто передать от от одного другому пароль. Это все ересь.
    шифровка и авторизация средствами апача - вещи несколько разные.
    уверен, что это фича, а не баг?
    чиво-чиво? это вообще к чему?
    разве что... но и контролировать ты ее тоже не сможешь.
    и то и другое. Изложение должно быть ясным и стройным.
    1. Возникла проблема такая-то.
    2. Увидел такие то пути решения.
    3. Выбрал такой-то путь, потому- что.
    4. Подробнее теории, как это быдет работать и зачем.
    4. Реализовал так и так, потому что...
    Аргументы. Нет реальных, весомых аргументов. Не оправданий, а аргументов.
     
  17. vb

    vb Активный пользователь

    С нами с:
    6 июн 2006
    Сообщения:
    911
    Симпатии:
    0
    Адрес:
    Saint-Petersburg
    По русски - хотел выпендриться - ну и зря :)
    Это плохо. Тут все знающие люди сидят только чтобы немного пообщаться и помочь новичкам. Большинство все же новички совсем зеленые. Поэтому все работы стараемся максимально доступно прокомментировать. А не новечкам не интересно сидеть в килограмах кода не зная зачем столько букв понаписано.
     
  18. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    (рассматриваю, хотя не при купленном сертификате запрос о переходе на другой протокол и выхода с него требует подтверждения пользователя .... что точно задалбливает)

    Откровенно говоря, рассмотри коллектив в 600 человек и нечестный админ (реально работал в таких условиях)
    да и много таких примеров ... домовые сети вот ещё пример .... или обмен ссылками на описание товара .... хотя желания передавть доступ к профилю и небыло, а тем ни менее случилось!

    ??? авторизация на основе шифрованного пароля ... по правилам протокала (для совместимости) помоему + больших размеров


    дык типа обсудили :)

    Дык! пример же привел ужо !!!

    в смысле ??? контролировать вид??? или что ?


    гм ... вот для исправления агрехов реализации я это здесь и выложил! - ну мало у меня знакомых ПХП программеров а обмена опытом очень нехватает!
    Изложение приму во внимание, хотя опять же повторюсь! класс скорее для занкомых с ситемой дигест и места его применения скорее вылезают из необходимости, чем из-за привычки или того что это "типа правильно"

    PS:ни за что не поверю что, никто из местных гуру не пробывал дигест и не думал как обойти его баги и поставить на служение своему коду! (система Дигест известна уже 1999 года и соответственно не поверю что гуры даже неслышали о нем, а коль слышали то и баги знают ... и теорию тем более, и наверняка и наработки есть, по решению его проблем)
     
  19. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    "хотел выпендриться" - нет не выпендрится .... совсем ... может что бы оценили .. да но точно не выпендрится - несчтиаю при своем уровне знаний это возможным

    а вот за "пообщатся" сюда и полез! :) смотрю на совершенно странные и непонятные вопросы отвечаете (особенно Горбунов Олег - его способность прочесть чужие мысли меня поражает .... но иногда ответы его тоже понять без телепатии нельзя)... код чужой тестите ... вот и не показалось что необходимо столь тщательно документировать свою писанину ... тем более что строчек несущих там раз два и обчелся .... а в целом работа класса - сабжект! :)
     
  20. vb

    vb Активный пользователь

    С нами с:
    6 июн 2006
    Сообщения:
    911
    Симпатии:
    0
    Адрес:
    Saint-Petersburg
    nimistar, Горбунов Олег - это большая умница :) Только работу можераторов нельзя обсуждать, либо хорошо либо никак - как и судей на поле :).
    По поводу недопонимания некоторых его ответов, у него хорошая подпись:
    В общем я думаю ты уже понял свои ошибки в подаче поста и дальше говорить тебе о том как все тут привыкли не имеет смысла. Главное не забывать о поколении некст, которое учится на всем о чем дядьки говорят.

    Ваш спор с Олегом разрешайте сами... :)

    p.s. лично я понимая что совсем забыл про форум из-за катастрофической нехватки премени/избытка лени, просто промотал весь код увидев пару знакомых слов и не увидев никакой вводни... думаю большинство сделало тоже самое.
     
  21. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    https - это не протокол :) это http внутри ssl. не знаю, что ты там насчитал, но подозреваю, что одного шифрующего фронт-сервера хватит за глаза.

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

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

    что пароль забыл в урле? и раз уж он что-то там забыл - почему он не одноразовый?

    хорошо сказано :)
     
  22. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    dark-demon - Добрый вечер!
    считал не я ... мне предаставили результат! - но я ему верю.... чем больше страничка тем больше нагрузка ... причем нелинейно .... а если ещё отдавать емкие файлы, а выход с ССЛ канала требует подтверждения, что для конечного пользователя неудобно!

    требовать не всегда возможно .... рамки проекта опускают сверху ... а изварачивайся как хошь!
    шифрование джавыСкрипта - накладывает определенные баги .. на работу формы (сам пробовал !) метод для постоянной работы негодится! что за полный контроль ??? откуда ??? :) шифруется методом который открыто отдали ??? неее шифрование жабой это временное решение .... либо не шифровать ... либо ссл .... ну вот третий вариант дигестом!!!


    врядли ... если перехват требует определенных усилий, то стоимость должна будет себя окупить!


    зачем пароль ... просто сид там светится ... и вместе с сидом уходит сессия.... проверка рефери порождает баги хистори.бек


    задача не в том чтобы спрятать содержимое ... а в том чтобы не дать работать с этим содержимым ... естественно, как я описал выше, для прятанья содержимого только ССЛ

    а вообще мной класс разрабатывался, как усиление зашиты и сессионого движка и самого дигеста! [/b]
     
  23. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    кто-то заставляет файло кидать по ssl?

    не требует, а опционально информирует пользователя об этом.

    показывай, как пробовал :)

    шифруется методом, который ты выбрал.

    если человек встрял в канал между клиентом и сервером - особых усилий не надо.

    сид - это временный пароль.
     
  24. nimistar

    nimistar Активный пользователь

    С нами с:
    30 май 2007
    Сообщения:
    919
    Симпатии:
    0
    dark-demon - давай стороннее обсудим, например в другой ветке?? а то как то твои замечания уже далеки от дигеста!

    свою позицию я объяснил! можешь не соглашаться!
    что можешь сказать насчет реализации ? не верняка и там есть спорные моменты!
     
  25. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    ладно, почему так:
    Код (Text):
    1. md5(md5($_SERVER['HTTP_USER_AGENT']).':'.md5($_SERVER['REMOTE_ADDR']).':'.md5($_SERVER['HTTP_HOST']));
    а не вот так:
    Код (Text):
    1. md5($_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'].$_SERVER['HTTP_HOST']);
    :?: