Безопасность PHP sha2: & $ salt = null? - PullRequest
3 голосов
/ 10 октября 2010

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

http://hungred.com/useful-information/php-better-hashing-password/

define('SALT_LENGTH', 15);

function HashMe($phrase, &$salt = null)
{
    $pepper = '!@#$%^&*()_+=-{}][;";/?<>.,';

    if ($salt == '')
    {
        $salt = substr(hash('sha512',uniqid(rand(), true).$pepper.microtime()), 0, SALT_LENGTH);
    }
    else
    {
        $salt = substr($salt, 0, SALT_LENGTH);
    }

    return hash('sha512',$salt . $pepper .  $phrase);
}

Какая разница, если я изменю функцию на эту?

function HashMe($phrase, $salt)  {..}

конечно, эта функция потерпит неудачу, для чего она должна иметь '&' перед $ salt? нужно ли иметь 'null' как это & ​​$ salt = null? что если я добавлю '& $ salt'?

и затем, чтобы получить солт-значение, вы просто можете получить его прямо и поставить SQL-запрос, как показано ниже,

$username = cleanMe($_POST('username'));
$password = cleanMe($_POST('password'));
$salt = '';
$hashed_password = HashMe($password, $salt);
$sqlquery = 'INSERT INTO  `usertable` ("username", "password", "salt") VALUES  ("'.$username.'", "'.$hashed_password .'", "'.$salt.'") WHERE 1';
..

как я могу получить значение соли из функции, как показано ниже, перед подготовкой запроса sql,

$salt = "'".salt."'";
$username = "'".$username."'";
$hashed_password = "'".$hashed_password."'";

тогда

$sqlquery = 'INSERT INTO  `usertable` ("username", "password", "salt") VALUES  ($username, $hashed_password, $salt) WHERE 1';

причина, по которой мне не нравится / не хочется иметь это - "'" в моем sql-запросе, заключается в том, что у меня иногда есть нулевое значение, например, $ firstname =' NULL '; и я хочу, чтобы строка «помечала» пустое поле как нулевое, если имя пустое / пустое.

кроме того, наличие "" "в моем sql-запросе вызывает головокружение и затрудняет отладку, когда что-то идет не так ...

извините, у меня много вопросов в этой теме!

спасибо.

1 Ответ

5 голосов
/ 10 октября 2010

Давайте посмотрим, смогу ли я ответить на ваши вопросы по одному.

Сначала вы спросили, почему function HashMe($phrase, $salt) терпит неудачу, а function HashMe($phrase,&$salt = null) - нет.Это станет ясно после объяснения частей второй и третьей.

Во-вторых, вы спросили, зачем вам нужен знак & before $salt в объявлении функции.Значение & означает, что вы передаете значение по ссылке .Обычно, когда вы передаете значение в функцию, создается копия этого значения, и вы работаете с ней.Например:

function addOne($number){
    $number = $number + 1;
}

$myNumber = 3;
addOne($myNumber);
echo $myNumber;

этот код будет выводить 3, а не 4.Это потому, что функция не меняет $ myNumber, она создает ее копию и изменяет эту копию.Когда вы передаете по ссылке, вы говорите, чтобы он работал с оригинальным номером, а не создавал копию.Поэтому, если мы сделаем это небольшое изменение:

function addOne(&$number){
    $number = $number + 1;
}

$myNumber = 3;
addOne($myNumber);
echo $myNumber;

Теперь наш код выведет 4.Функция передает $ salt по ссылке, поскольку она изменяет значение $ salt.Поэтому после запуска функции у вас теперь есть новое значение $ salt.

Что касается необходимости &$salt = null, то переменная автоматически объявляется, если вы не объявляете ее самостоятельно.Поэтому, если вы хотите просто сгенерировать случайный хеш (без возможности воссоздать его, так как вы не знаете, какая соль использовалась), вы можете просто вызвать функцию с помощью HashMe("message to hash");.= null означает, что если второго параметра не было, автоматически установите для второго параметра значение «ноль».Однако позже в коде говорится, что если второй параметр имеет значение «null», сгенерируйте случайную соль:

if ($salt == '')
{
    $salt = substr(hash('sha512',uniqid(rand(), true).$pepper.microtime()), 0, SALT_LENGTH);
}

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

В своем четвертом вопросе вы хотели получить значение $ salt для использования в запросе SQL.Это красота передачи по ссылке.Поскольку переменная $ salt была передана по ссылке, после запуска функции вы можете просто снова использовать $ salt, и она получит новое значение.Следует отметить одну важную вещь: все, что делает функция для изменения $ salt, - это гарантия того, что она имеет длину 15 символов.Все, что больше, обрезается, но все, что короче, останется нетронутым.По этой причине, если вы храните (15-символьную) соль, возвращаемую функцией, вы можете использовать ее в будущем, и она больше не изменит соль.Таким образом, ваш SQL-запрос должен работать идеально.

$sqlquery = "INSERT INTO  `usertable` ('username', 'password', 'salt') VALUES  ($username, $hashed_password, $salt) WHERE 1";

Обратите внимание, что я поменял двойные и одинарные кавычки из вашего исходного запроса.Это связано с тем, что в некоторых версиях PHP переменные не будут анализироваться в одинарных кавычках.Например:

$secret = "Hello, there";
echo '$secret'; // "$secret"
echo "$secret"; // "Hello, there"
...