php соли мои пароли для каждого пользователя sha512 - правильно ли я это делаю?

Я пытаюсь правильно настроить соль для каждого пользователя и сайта для своих паролей. Вот что у меня есть:

require('../../salt.php'); //this is above the web root and provides $salt variable
$pw = mysql_real_escape_string($_POST['pw']);
$per_user_salt = uniqid(mt_rand());
$site_salt = $salt //from salt.php that was required on first line
$combine = $pw . $per_user_salt . $site_salt;
$pw_to_put_in_db = hash("sha512", $combine);

Это правильно? Спасибо


person Andrew Samuelsen    schedule 25.06.2011    source источник
comment
На самом деле это не ответ на вопрос, правильно ли вы это делаете. (1) Нет необходимости использовать mysql_real_escape_string. Результирующее hash() изменит любой недопустимый SQL на букву/цифру. (2) Убедитесь, что вы храните свой $per_user_salt безопасным и надежным способом, чтобы получить его, когда ваши пользователи пытаются войти в систему со своим паролем.   -  person Charles Sprayberry    schedule 25.06.2011
comment
@Charles Sprayberry, для хранения - нужно ли мне делать что-то кроме INSERT INTO users (per_user_salt) VALUES ($per_user_salt)?   -  person Andrew Samuelsen    schedule 25.06.2011
comment
@Andypandy - Если предположить, что это единственное поле, которое вы хотите сохранить в таблице пользователей, почти. Убедитесь, что вы заключаете $per_user_salt в кавычки (одинарные или двойные), так как ваш хэш представляет собой строку (например, INSERT INTO users (per_user_salt) VALUES ('$per_user_salt').   -  person Francois Deschenes    schedule 25.06.2011
comment
Почему вы храните «соль пользователя»? Не лучше ли сделать алгоритм, который зависит от данных, уже имеющихся в базе данных, что делает менее очевидным, какая соль была использована? Это никоим образом не является обязательным требованием, но может сделать ваши пароли немного более безопасными.   -  person KilZone    schedule 25.06.2011
comment
Разве вы не должны использовать mysql_real_escape_string() прямо перед запросом к базе данных, а не в начале?   -  person maaudet    schedule 25.06.2011
comment
@manhim, поправьте меня, если я ошибаюсь, но единственная часть, открытая для инъекции sql, - это пользовательский ввод для «pw», моя соль и per_user_salt генерируются мной ... однако, согласно @charles sprayberry, мне даже не нужно чтобы сбежать от pw там, так как я его хеширую... я собираюсь оставить его, потому что мне нужно, чтобы он сбежал и в другом месте...   -  person Andrew Samuelsen    schedule 25.06.2011
comment
@kilzone, я не уверен, что вы имеете в виду - я думаю, что это алгоритм, основанный на данных в базе данных ... данные - это per_user_salt, и алгоритм объединяет salt . pw . per_user_salt, а затем хеширование ... если у вас есть лучшая рекомендация, пожалуйста дайте мне знать... я никогда не делал этого раньше..   -  person Andrew Samuelsen    schedule 25.06.2011
comment
@Andypandy Поскольку вы хэшируете, вам не нужна эта функция. В большинстве случаев результат должен быть буквенно-цифровым.   -  person maaudet    schedule 25.06.2011
comment
@andy Ну, например, если вы используете md5($_POST['pw']) в качестве «соли», у вас есть соль, которая зависит от пользователя, но ее не нужно хранить в базе данных. Ваш хэш будет hash("sha512", $pw . md5($pw) . $site_salt);, что примерно так же безопасно, как случайно сгенерированное число (пока вы никому не говорите свой алгоритм). Большим преимуществом является то, что взлом вашей базы данных (например, с помощью инъекции) не приведет к отображению per_user_salt, так как это не stored.   -  person KilZone    schedule 25.06.2011
comment
@kilzone, я понимаю, что вы говорите - так что, если бы я изменил свой $combine на $combine = $pw . $per_user_salt . $site_salt . $site_salt . $per_user_salt . $pw;, это было бы более безопасно ...? или есть более простой способ сделать его более безопасным, например $combine = $pw . $per_user_salt . $site_salt . md5($pw);...   -  person Andrew Samuelsen    schedule 25.06.2011
comment
@andy Весь смысл «соли» заключается в том, чтобы избежать использования радужных таблиц для дехэширования чего-либо в пароль, поэтому все, что вы делаете до хеширования, делает его более безопасным. Оба варианта более безопасны, так как $combine становится более сложным, но мне больше нравится ваш последний вариант. Однако в конечном итоге все сводится к личным предпочтениям. Просто помните, что ваш salt-трюк — это форма безопасности через неизвестность, и чем меньше людей знают о том, как вы делаете $combine, тем лучше. Попробуйте придумать что-нибудь необычное, вроде тех двух, которые вы только что опубликовали, и все будет в порядке.   -  person KilZone    schedule 25.06.2011
comment
@kilzone, еще один вопрос - как лучше защитить алгоритм?   -  person Andrew Samuelsen    schedule 25.06.2011
comment
Проблема в том, что PHP не имеет «скомпилированной» структуры кода (если вы не используете Zend Guard, но это слишком дорого), поэтому любой, кто получит доступ к вашему PHP-серверу, может просто прочитать текстовую версию вашего алгоритма. Лучше всего не хранить свой хеш-код в корневом каталоге (предпочтительно в папке над корнем, а если это невозможно, используйте подпапку) и никому не говорить об этом и о том, как вы солите пароли.   -  person KilZone    schedule 25.06.2011
comment
Эта статья может представлять интерес: codahale.com/how-to-safely- сохранить пароль   -  person Sven Koschnicke    schedule 29.06.2011
comment
@ Свен, черт возьми, я собирался сказать это прямо сейчас!   -  person Ahmet Alp Balkan    schedule 01.07.2011


Ответы (4)


часто люди используют уникальную соль, связанную с паролем, а затем используют метод hmac для добавления хэш-ключа для всего сайта:

http://www.php.net/manual/en/function.hash-hmac.php

$password = hash_hmac('sha512', $password . $salt, $sitewide_key);
person dqhendricks    schedule 25.06.2011
comment
кстати, ваша уникальная соль должна быть одинаковой каждый раз, когда вы хешируете пароль для сравнения. это означает, что вам придется где-то хранить уникальную соль для этого пользователя. иногда по этой причине люди используют строку, основанную на имени пользователя. $ соль = substr (md5 ($ имя пользователя), 1); или что-то еще в зависимости от вашего уровня безопасности. это значительно упрощает поиск в базе данных. - person dqhendricks; 25.06.2011
comment
если ваш алгоритм станет достоянием общественности, хорошим советом может быть использование общего ключа вашего сайта при создании вашей соли. $ соль = md5 ($ имя пользователя . $ sitewide_key); - person dqhendricks; 25.06.2011
comment
@Andypandy без проблем. Рад, что смог помочь. - person dqhendricks; 25.06.2011

Все в порядке, просто удалили "" из "sha512" :)

$pw = $_POST['pw'];
$per_user_salt = uniqid(mt_rand());
$site_salt = $salt //from salt.php that was required on first line
$combine = $pw . $per_user_salt . $site_salt;
$pw_to_put_in_db = hash(sha512, $combine);

не нужно использовать md5 sha512 сам по себе достаточно безопасен

person deerox    schedule 08.06.2013

Используйте crypt, он доступен на всех языках, и ваши хэши паролей будут использоваться и другими программами:

$hash = crypt("secret", "$6$randomsalt$");
person lathspell    schedule 13.06.2013

Основываясь на комментариях, вот что я собираюсь сделать: изменить мой $combine на что-то уникальное для каждого пользователя, но не сохраненное в БД. Что-то вроде: $combine = $pw . md5($pw) . 'PoniesAreMagical' . $site_salt . md5($pw); и т.д. и т.д. и т.п... Спасибо за помощь...

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

person Andrew Samuelsen    schedule 01.07.2011
comment
я не думаю, что это лучший вариант, и я не согласен с @killzone в комментариях к вашему вопросу. идея соли состоит в том, чтобы предотвратить атаки радужных таблиц с помощью уникальных солей пользователя. даже со знанием вашего алгоритма невозможно создать радужные таблицы. если вы используете md5($w) в качестве соли, любой, кто знает внутренности вашего алгоритма, может легко создать радужную таблицу для всей вашей пользовательской базы — в конце концов, у него есть все необходимые входные данные: пароль, хэш пароля (легко вычисляемый), пони- постоянная, а сайт-соль. безопасность через неясность никогда не работает! - person knittl; 01.07.2011
comment
лучше и проще всего просто создать случайную соль для каждого пользователя и сохранить ее в БД. таким образом, соль уникальна для каждого пользователя и не может быть получена из других входных данных (например, пароля) — поэтому она не поможет плохим парням, если они узнают ваш алгоритм. - person knittl; 01.07.2011