Нужно ли base64 кодировать мою соль (для хеширования паролей)?

Извините за этот очень странный вопрос. Я понимаю цель кодирования base64 для передачи данных (то есть кодирование MIME Base64), но я не знаю, нужно ли мне кодировать base64 мои соли.

Я написал вспомогательный класс (действительно базовый абстрактный класс):

use Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;

abstract class AbstractCryptPasswordEncoder extends BasePasswordEncoder
{
    /**
     * @return string
     */
    protected abstract function getSaltPrefix();

    /**
     * @return string
     */
    protected abstract function getSalt();

    /**
     * {@inheritdoc}
     */
    public function encodePassword($raw, $salt = null)
    {
        return crypt($raw, $this->getSaltPrefix().$this->getSalt());
    }

    /**
     * {@inheritdoc}
     */
    public function isPasswordValid($encoded, $raw, $salt = null)
    {
        return $encoded === crypt($raw, $encoded);
    }
}

Реальный класс реализации будет:

class Sha512CryptPasswordEncoder extends AbstractCryptPasswordEncoder
{
    /**
     * @var string
     */
    private $rounds;

    /**
     * @param null|int $rounds The number of hashing loops
     */
    public function __construct($rounds = null)
    {
        $this->rounds = $rounds;
    }

    /**
     * {@inheritdoc}
     */
    protected  function getSaltPrefix()
    {
        return sprintf('$6$%s', $this->rounds ? "rounds={$this->rounds}$" : '');
    }

    /**
     * {@inheritdoc}
     */
    protected function getSalt()
    {
        return base64_encode(openssl_random_pseudo_bytes(12));
    }
}

Ключевой частью является генерация соли, которая будет встроена в пароль: нужно ли мне base64_encode по какой-либо причине (хранение), предполагая, что он никогда не будет отправлен по проводам?

2 ответа

Решение

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

Возьмем, к примеру, BCrypt, это хороший алгоритм хеширования для паролей (SHA-512 не подходит, потому что он слишком быстрый), он принимает все символы строки в кодировке base64, кроме символа "+". С другой стороны он принимает "." символы, которые не являются частью строки в кодировке base64.

PHP 5.5 будет иметь функции password_hash() а также password_verify() готов, чтобы сделать использование BCrypt проще, я действительно могу рекомендовать их. Также есть пакет совместимости для более старых версий PHP, в строке 121 вы можете увидеть, что base64_encode() действительно используется, но после этого все недопустимые символы "+" заменяются разрешенными "." персонажи:

Кодировка соли для BCrypt:

$salt = str_replace('+', '.', base64_encode($buffer));

BASE64 используется для кодирования двоичных данных в текстовое представление. Это позволяет передавать двоичные данные по текстовым каналам. Если вы хотите сохранить хешированный пароль в БД, вам не нужно его кодировать - он уже в текстовом формате.

Другие вопросы по тегам