+1 к защите пароля методом тройного хеширования. Бред?

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



Регистрация:

Человек генерирует md5 пароля (не передавая сам пароль, в чем нет нужды), отправляет на сервер, где высчитывается еще одна сумма (md5(hash)) === md5(md5(password)) и добавляется в поле hash_of_hash таблицы с юзерами. Операция небезопасна, так как хеш может быть перехвачен и использован для авторизации (хеш пароля, образно выражаясь, сам стал паролем), поэтому требуется удача или безопасный канал связи. Этот ход нужен, как было указано выше, только для невозможности получения исходного пароля после хищения злоуышленником базы (известно, что многие используют один и тот же пароль и для вконтактика и для интернет-банка, например).



Авторизация:

1. Клиент (в данном случае браузер) запрашивает рандомый ключ (например, 1234) по открытому каналу связи.

2. Отправляет на сервер md5(md5(md5(password))+1234) = «qwer», сгенерированный JS кодом

3. Сервер делает запрос к базе:

(SQL-подобный псевдокод)

SELECT user FROM users WHERE md5(hash_of_hash+1234) = «qwer»



И авторизует соответствующего юзера. Рандомный ключ уникален для каждого запроса этого ключа. Трафик всё еще можно подслушать, но, вот, «войти» будет гораздо сложнее (по крайней мере, юзер будет знать, если его данные перехватил «человек по середине»).



Совсем идиотизм? Или способ имеет право на жизнь (хотя бы часть с авторизацией, используя двойное хеширование против тройного).
  • Вопрос задан
  • 3921 просмотр
Пригласить эксперта
Ответы на вопрос 11
@newpavlov
Скорее всего, вы пытаетесь переизобрести SRP.
Ответ написан
@bondbig
hash+salt и не надо ничего изобретать. Ну и не использовать md5, обнаружены слабости к коллизиям, лучше sha2.
Ответ написан
Комментировать
bobermaniac
@bobermaniac
Нет никакой разницы, что использовать в качестве первичной информации — пароль, его хеш, его сумму с какой-то известной строкой или любое другое однозначное преобразование.

Криптостойкость системы от этого ни возрастает, ни падает.
Ответ написан
Комментировать
NeverWalkAloner
@NeverWalkAloner
Дык это, если злоумышленник уведет базу hash_of_hash, как вы ее называете, то он сможет спокойно авторизовываться в качестве любого пользователя в дальнейшем, разве нет? Например, Ева знает hash_of_hash Алисы. Ева запрашивает ключ. Получает 1234. Вычисляет md5(hash_of_hash+1234) отправляет все дело серваку. Тот вычисляет md5(hash_of_hash+1234) и Ева внутри. Получается что в базе у вас будут лежать данные, используя которые злоумышленник может успешно авторизоваться. А это не есть хорошо.:)
Ответ написан
Комментировать
denver
@denver
Хэш как пароль приведет к конечному количеству комбинаций. 30^32 — не так уж мало, но пароль вида "C6+~Z4tx==n порой может быть даже помощнее чем полученный от него хэш.

Затем, переводя все пароли в md5(pass) вы делаете так, что некоторых разных паролей md5 совпадает (из-за коллизий), что тоже не хорошо. А делая md5(md5(md5(x))) — вы только увеличиваете коллизии, также как sin(sin(sin(x))) только упростит график sin. Соответственно только вредит.
Ответ написан
Tesby
@Tesby
А использовать sha512 разве не эффективнее?
Я юзаю так, например: base64_encode(hash('sha512', $password.$salt));
но у меня обычно хитрее все%)
Ответ написан
Комментировать
BupycNet
@BupycNet
Основатель PushAll
Ну, если подумать имея рандомный ключ и имея хэш с этим ключем особо ничего не сделать. Это только если этот ключ будет меняться. По сути вытащить пароль не выйдет и исполовать хэш тоже не выйдет. Но только учтите что делать придется так, юзер вводит пароль он хэшируется, потом вместе с ключем. то есть
md5(md5(password)+1234) (синтаксис схожий с js)
Все это дело отправляется на сервак, там мы имеем захэшированный пароль и ключ (храним в сессии например) и делать надо что то вроде
SELECT id FROM users WHERE md5(phw.'.$key.') = '.$phw.' limit 1;
тогда в общем то все безопасно при перехвате.
Ответ написан
Комментировать
Shedal
@Shedal
Можно ещё по-другому поступить. Выбрать один из криптоалгоритмов, в которых шифрование можно производить открытым ключём, а дешифрование — закрытым. Передавать брузеру открытый ключ, принимать зашифрованный пароль, и дешифровать его на серверной стороне закрытым ключём.
В этом случае, перехват открытого ключа ничего злоумышленнику не даст, т.к. им можно только зашифровать, но не расшифровать.
Перехват зашифрованного пароля тоже ничего не даст, т.к. закрытый ключ есть только у сервера.

Ну, и хранить пароли в БД классически: hash + salt.

P.S. А не проще ли на страничке авторизации ввести https?
Ответ написан
strib
@strib
Реальное усиление стойкости — введение многфакторной аутентификации.
Ответ написан
Комментировать
demark
@demark
Посмотрите как сделали в Stripe — они используют асимметричное шифрование и передают данные кредитки в виде токена.

Уже есть jQuery плагин jCryption, который работает по такой схеме (цитата с сайта):
1) Client chooses a Password … (in the example a weak one, you should use a good random number in production e.g. mousemovement coordinates)
2) Client requests RSA Public key from Server
3) Client encrypts Password with RSA Public key
4) Server decrypts Password and stores it in the session
5) Server Encrypts the Password with AES and sends it back to the Client
6) Client decrypts it with AES with the Password
7) Both have now the same “secret” key which is used for communication
Ответ написан
woonem
@woonem
E меня была похожая идея, вы не один :)
Вот что удалось найти в заметках.

Персонажи:
Алиса - Сервер.
Боб - Клиент.
Сэм - Злоумышленник.

Принцип действия:
1. Боб запрашивает у Алисы key и keyid.
2. Алиса генерирует случайное число key и записывает в свою базу данных такие значения:
"key"=key, "keyid"=keyid, "expires"=(текущая дата плюс 2 минуты).
3. Алиса отправляет Бобу key и keyid (у Сэма появились key и keyid).
4. Боб отправляет Алисе такие данные:
"login"=login, "encripted_pass"=md5(key||pass||key), "keyid"=keyid (у Сэма появились login, encripted_pass).
5. Алиса достает expires, соответствующий keyid из своей базы данных. Если expires меньше текущей даты, Алиса отправляет Бобу ошибку "Timed out". Иначе, выполняются следующие шаги.
6. Алиса достает pass, соответствующий login и key, соответствующий keyid из своей базы данных. Вычисляет md5(key||pass||key) и сравнивает с encripted_pass. Если вычисления совпали, авторизация пройдена.
7. Алиса, независимо от того, успешна ли авторизация, записывает в строку expires, соответствующую значению keyid, значение "false".

У Сэма есть значения key, keyid, login, encrypted_pass.
Он не может повторно использовать encrypted_pass, так как "expires"="false" в поле, соответствующем keyid в базе данных Алисы.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы