Ответ 1
Короткий ответ
Не делай этого. Вы пожалеете об этом в долгосрочной перспективе. Конечно, вы можете зашифровать его, но что происходит, когда кто-то выясняет ваш ключ шифрования. Теперь вы просто передали им все права на тарелку (ну, не совсем, но достаточно близко).
Лучший способ сделать это
Вместо того, чтобы хранить имя пользователя и пароль в зашифрованном виде, почему бы не создать произвольный токен и сохранить его с именем пользователя? Вам нужно что-то значимое, поэтому достаточно хеша sha256
.
$randomToken = hash('sha256',uniq_id(mt_rand(), true).uniq_id(mt_rand(), true));
Затем сохраните его в db вдоль стороны пользователя и отправьте куки файл клиенту (я также предложил бы подписать токен, чтобы предотвратить фальсификацию:
$randomToken .= ':'.hash_hmac('md5', $randomToken, $serverKey);
Теперь, когда вы проверите, сначала проверьте, соответствует ли хеш:
list($token, $hmac) = explode(':', $_COOKIE['remember_me'], 2);
if ($hmac != hash_hmac('md5', $token, $serverKey)) {
die('tampered token!');
}
Оттуда просто найдите пользователя по токену. Если вы его найдете, зарегистрируйте этого пользователя.
Я также предлагаю изменить токен при каждом изменении пароля.
Чтобы ответить на ваш вопрос напрямую
Примечание: не делать этого в режиме реального времени, производственный код. Вы никогда не сможете полностью доверять данным, которые покидают ваш веб-сервер. Поэтому не подвергайте свою информацию пользователю подобным образом. Это не стоит. Однако я добавил некоторые дополнительные проверки (например, подписание cookie), чтобы сделать их более безопасными, но вы были предупреждены...
Чтобы закодировать его, я бы использовал mcrypt
для шифрования данных в файл cookie. Затем я сделал бы случайную соль и сохранил ее с пользовательской строкой, а затем подпишите зашифрованные данные с помощью hash_hmac
, используя эту уникальную соль. Таким образом, если кто-то перехватывает файл cookie и, выдает ключ для шифрования, вы все равно можете обнаружить недопустимый hmac, чтобы вы могли найти тамперы.
function generateCredentialsCookie($user_id, $password) {
$encrypted = encrypt($user_id.':'.$password, $secretkey);
$salt = uniq_id(mt_rand(), true);
$encrypted .= ':'.hash_hmac('sha256', $encrypted, $salt);
storeSaltForUser($user_id, $salt);
set_cookie('credentials', $encrypted);
}
function readCredentialsCookie() {
$parts = explode(':', $_COOKIE['credentials']);
$salt = array_pop($parts);
$encrypted = implode(':', $parts); //needed incase mcrypt added `:`
$raw = decrypt($encrypted, $secretkey);
list ($user_id, $password) = explode(':', $raw, 2);
if ($salt == getSaltForUser($user_id))
return array($user_id, $password);
} else {
return die('Invalid Cookie Found');
}
}
Примечание - этот псевдокод. Вам понадобится гораздо больше, чтобы быть безопасным (например, проверка недопустимых значений, их успешное дешифрование и т.д.).
НЕ использовать длительные сеансы!
Вы должны придерживаться минимального срока действия сеанса (обычно я использую 30-минутные сеансы, но некоторые сайты ниже). Время истечения срока действия после последнего использования, так что пока сайт активно используется, это не имеет значения.
Что касается того, почему бы не использовать длительный сеанс, вот несколько минусов:
-
Созданы уязвимости DOS (Denial Of Service)
-
Место на диске - каждый сеанс использует достаточно небольшой объем дискового пространства. Но когда у вас длительная сессия, каждый новый сеанс добавляет только к предыдущей сумме. Таким образом, при длительных сеансах кому-то просто нужно постоянно посещать ваш сайт с новым идентификатором сеанса, и внезапно вы покидаете дисковое пространство (при условии, что у вас есть разумный диск).
-
Папка - каждый сеанс занимает один файл в одной папке. Самые популярные файловые системы замедлятся с большим количеством файлов в одной папке. Поэтому, если вы поместите 1 миллион файлов сеанса, чтение или запись в файл сеанса будет медленным (очень медленным). И сборка мусора (которая очищает старые файлы) будет ОЧЕНЬ ОЧЕНЬ ОЧЕНЬ медленной (если она вообще запустится).
-
-
Уязвимость сеанса открыта. Это связано с тем, что чем больше сеансов у вас открыто на сайте, тем легче будет угадать действительный идентификатор (благодаря атаке на день рождения). Чем меньше сеансов у вас есть, тем труднее будет угадать действительный.
Есть, вероятно, другие, но это быстрый обзор. Вместо длительных сеансов используйте подписанный токен mem-me, как описано выше. Вам будет намного лучше, и гораздо безопаснее...