Новости из Блогов Хранение паролей пользователей

Discussion in 'Мировые новости. Обсуждения.' started by d3l3t3, 11 Jun 2012.

  1. d3l3t3

    d3l3t3 Banned

    Joined:
    3 Dec 2010
    Messages:
    1,771
    Likes Received:
    98
    Reputations:
    10
    Хранение паролей пользователей



    [​IMG]

    Любой разработчик рано или поздно сталкивался с проблемой, которая заключалась в том, как ему правильно организовать хранение паролей зарегистрированных пользователей в БД.

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

    В этой статье я попытаюсь рассмотреть минусы хранения открытых паролей в БД. Попытаюсь убедить в необходимости хешировать каждый пароль. Также попытаюсь объяснить зачем нужна "соль" и какой она бывает. Ну и в кратце расскажу про разные алгоритмы хеширования.

    Зачем?

    Для начала нам необходимо понять зачем вообще нужно правильно хранить пароли. Правильно организованный алгоритм хранения паролей должен:
    • Снизить риск полного взлома системы
    • Предотвратить утечку паролей пользователей

    Рассмотрим когда система имеет какие-либо теоретические уязвимости. Неправильный алгоритм позволит в первом случае получить пароль администратора через некую имеющуюся уязвимость, далее попасть в админ-панель, и далее по обстановке, т.е. в 90% случаев это означает полный взлом. Во втором случае если злоумышленник каким-то образом получает базу всех паролей, то это позволит скомпрометировать некоторых пользоватлей, которые, к примеру, используют один пароль на все ресурсы. Правильный же алгоритм должен вообще предотвратить получение злоумшленником паролей.

    На практике это выглядит так. Злоумышленник находит на сайте SQL-injection, через которую получает логин-пароли всех пользователей. При правильной системе хранения паролей злоумышленник получает не исходные пароли а только их хеш суммы (см.далее).

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

    Хеш сумма

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

    Что такое хеш сумма? Допустим у пользователя пароль "123456". Придумаем свою хеш-функцию. Сложим все цифры получим число "21" - это и будет являтся результатом нашей хеш функции, хеш-суммой или хешем. Конечно наш алгоритм отвратителен (да и хеш суммой его назвать нельзя, это скорее контрольная сумма), так как один и тотже хеш может соответствовать большому колличеству различных паролей. То есть пароли "654321", "555222", "100299" и т.д будут давать такой же хеш, или по-научному будут являтся коллизией.

    Идеальная хеш функция должна обладать следующими параметрами:
    • Необратимость - хеш сумма не должна "расшифровываться" подобно обычным алгоритмам шифрования
    • Отсутствие коллизий - для каждых данных проходящих через хеш-функцию должен получится уникальный хеш

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

    И теперь при регистрации пользователя, указанный им пароль проходит через хеш-функцию и вместо пароля в БД будет занесен полученный хеш. При каждой попытке авторизации указанный пароль будет каждый раз проходить через хеш-функцию и полученный хеш будет сравниваться с хешем хранимым в БД, и если хеши будут соответствовать значит пароль был указан верный. Вообщем как то так:

    [​IMG]

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

    "Соленые" хеши

    Вообщем все бы хорошо, но если бы не ленивые или забывчивые пользователи которые стремятся использовать максимально короткие и простые пароли... Почему это плохо? Потому что сбрутить короткие пароли можно в считанные минуты, а простые (часто используемые) пароли брутятся по словарям.

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

    Как же нам защитить пользователей и свой ресурс в случае его взлома? На помощь проходит соль. Грубо говоря соль - это набор случайный символов который каждый раз перед прохождением через хеш-функцию добавляется к паролю. При регистрации пользователя генерируется случайная соль, на основе которой и указанного пароля генерируется "соленый" хеш, при этом соль также заносится в БД:

    [​IMG]

    Что дает соль в этом случае? Если подумать, то если злоумышленник имеет доступ к хешам пользователей, то если соль каждого хеша мы храним рядом (в той же таблице/БД), то злоумышленник также будет иметь и доступ к соли. То есть сможет найти исходный пароль методом брутофорса, но словари ему уже не подойдут, так как не существует словарей учитывающих все комбинации паролей с солью.

    Теперь рассмотрим второй плюс. Допустим вы владеете ресурсом с десяткой тысяч зарегестрированных пользователей. Каждый пароль пользователя имеет уникальную соль. Что это даст? Это даст невозможность одновременного брута хешей всех пользователей, так как для каждой соли нам прийдется генерировать новый хеш. И если вдруг злоумышленник сбрутить все аккаунты, то ему прийдется на каждый вариант пароля генерировать столько хешей сколько пользователей у вас имеется. При этом скорость брутофорса упадет пропорционально. Допустим скорость брута - 1милион паролей в секунду. В нашем случае (десять тысяч пользователей) скорость брута упадет до 100 паролей в секунду. Согласитесь, брутить всех бессмысленно? Разве что по простейшим и коротким словарям...

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

    Дважды "соленый" хеш

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

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

    Давайте немного порассуждаем. Отставьте в сторону в свои выпады в стиле "надо предполагать что взломщик имеет полный доступ к всей системе и такая соль бессмысленна". Представьте ситуацию, которую я описывал выше, в вашей системе имеется уязвимость по типу SQL-injection, через которую злоумышленнику удалось получить администраторский хеш и соль из БД. Далее злоумышленнику удалось и сбрутить хеш - и все, ваша система, считайте, взломанна.

    А ведь наличие дополнительной соли не дало бы злоумышленнику взломать систему, так как ему бы пришлось брутить еще и соль (а это скорее всего будет бесполезным занятием). Да, вы опять можете сказать, что "надо предполагать что взломщик имеет полный доступ к всей системе". Но вдумайтесь, зачем тогда злоумышленнику брутить пароль администратора если он уже имеет полный доступ ко всей системе? Да, теоретически вероятны атаки на других пользователей, кроме администраторов, но на моей практике я не слышал ни об одном таком случае.

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

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

    [​IMG]

    При этом проверка правильности пароля при авторизации будет выглядеть так:

    [​IMG]

    Алгоритмы хеширования

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

    Теперь представьте что мы используем алгоритм который позволяет генерировать хеши со скоростью лишь тысяча или сотня хешей в секунду. Такой хеш в купе с паролем хотябы в 10-12 знаков будет подбираться значительно дольше чем "разумное время", и смысла такой подбор иметь не будет.

    К примеру на моем ноуте:
    • MD5 - 2 200 000 паролей/сек
    • SHA - 800 000 паролей/сек
    • MD5(unix) - 1 200 паролей/сек

    Теперь давайте добавим немного математики, и подсчитаем среднее время, которое понадобится нам для перебора простенького пароля из 6 симолов латиницы верхнего и нижнего регистров и цифр. То есть это всего около 100 000 000 000 комбинаций.
    • Для MD5 ~45 000 секунд или ~12 часов
    • Для SHA ~125 000 секунд или ~35 часов
    • Для MD5(unix) ~83 300 000 секунд или ~23 100 часов или ~3 года

    Причем для md5 и sha брут еще как-то более-менее имеет смысл, то брутить md5(unix), на мой взгляд, смысла нет абсолютно. Кстати, для справки, в основе md5(unix) лежит тысяча иттераций обычного md5.

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

    Коллизии

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

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

    Но у меня вроде как возникла еще одна идея для решения этой проблемы, но об этом в одной из следующих статей ;)

    Итог

    Вот основные правила которые вы должны были понять из этой статьи:
    • Пароль не должен хранится в БД в открытом виде, а должна хранится лишь хеш-сумма
    • При регистрации пользователя желательно рекомендовать (но не вынуждать!) использовать более сложный пароль
    • Каждый пользовательский хеш необходимо генерировать с уникальной солью
    • К пользовательской соли должна быть добавленна общая соль, которая хранится в другом месте (отдельно от пользовательских данных)
    • Соль должна быть достаточно длинной
    • Алгоритм вычисления хеш суммы должен быть ресурсоемок (но не вешать ресурс напрочь)

    Дата: 10.06.2012 02:28 (Изменено: 10.06.2012 02:30)
    Автор: Intellect
    http://intsystem.org/687/users-passwords-store/
     
  2. Edward

    Edward Banned

    Joined:
    11 Feb 2010
    Messages:
    329
    Likes Received:
    21
    Reputations:
    -1
    Спасибо, хорошая статья !
     
  3. LibertyPaul

    LibertyPaul New Member

    Joined:
    16 Jan 2010
    Messages:
    36
    Likes Received:
    0
    Reputations:
    0
    статья гуд. про общую соль спасибо за идею, как то я про это не думал, а это очень эффективная защита от подбора.
     
  4. LibertyPaul

    LibertyPaul New Member

    Joined:
    16 Jan 2010
    Messages:
    36
    Likes Received:
    0
    Reputations:
    0
    вот только никак не врублюсь, почему крупные проекты не реализовывают такую достаточно простую схему? тот же LinkedIn в пример.
     
  5. KosmoBoy

    KosmoBoy New Member

    Joined:
    21 Jun 2012
    Messages:
    3
    Likes Received:
    0
    Reputations:
    0
    На нашем предприятии сейчас пытаются внедрить такую систему, но говорят что есть свои сложности. Видимо не всё так плохо... :rolleyes:
     
  6. justonline

    justonline network ninja

    Joined:
    27 Jul 2011
    Messages:
    499
    Likes Received:
    60
    Reputations:
    53
    боятся положить сервера вычислениями. :) если код не уязвим то можно хоть в открытом виде хранить
     
  7. RG_vk

    RG_vk New Member

    Joined:
    21 Jun 2012
    Messages:
    1
    Likes Received:
    0
    Reputations:
    0
    Спасибо, и вправду интересная статья
     
  8. LibertyPaul

    LibertyPaul New Member

    Joined:
    16 Jan 2010
    Messages:
    36
    Likes Received:
    0
    Reputations:
    0
    готов поспорить что любая система уязвима. на том или ином уровне.
     
  9. proroot

    proroot Member

    Joined:
    31 Jan 2012
    Messages:
    46
    Likes Received:
    5
    Reputations:
    0
    Спасибо за статью
     
  10. mironich

    mironich Elder - Старейшина

    Joined:
    27 Feb 2011
    Messages:
    733
    Likes Received:
    73
    Reputations:
    19
    Мб потому что хеширование в несколько алгоритмов занимает чуть больше время, и некоторые считают это лишней нагрузкой.
     
  11. Strilo4ka

    Strilo4ka

    Joined:
    5 Apr 2009
    Messages:
    709
    Likes Received:
    729
    Reputations:
    948
    Чтоб голова не болела у себя, то можно использовать третьи стороны для авторизации типо фейсбука, гугля и т.д..
     
  12. Lector

    Lector New Member

    Joined:
    17 Apr 2011
    Messages:
    8
    Likes Received:
    0
    Reputations:
    0
    В случае потери или угона акка, ты теряешь пользователя...Другой вопрос что если это чисто для комментов, то подойдет любой пользователь..
     
  13. Maser_Montan

    Maser_Montan Banned

    Joined:
    11 Mar 2013
    Messages:
    10
    Likes Received:
    1
    Reputations:
    0
    Спасибо, хорошая статья !
     
  14. Sequence

    Sequence New Member

    Joined:
    15 Aug 2015
    Messages:
    7
    Likes Received:
    0
    Reputations:
    0
    Статья заинтересовала, только от кого шифроваться? Надо - получат пароли. Силой выпытают.
     
  15. DiabloZet

    DiabloZet New Member

    Joined:
    23 Sep 2015
    Messages:
    4
    Likes Received:
    0
    Reputations:
    0
    Если хранить пароли в открытом виде, то однозначно их можно будет взломать банальным подбором md5==хеш, про время не говорю, но алгоритм возможен...:confused:
     
Loading...