Do I need base64 encode my salt (for hashing passwords)?

怎甘沉沦 提交于 2020-01-05 05:55:25

问题


Excuse me for this very odd question. I understand the purpose of base64 encoding for transmitting data (i.e. MIME's Base64 encoding), but I don't know if I need to base64 encode my salts.

I wrote an utility class (a base abstract class indeed):

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);
    }
}

A real implementation class would be:

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));
    }
}

The key part is the salt generation, which will be embedded in the password: do I need base64_encode for any reason (storing), assuming that it will be never sent over the wire?


回答1:


Each hash algorithm expects a salt in a given alphabet, that means using base64_encode() can be the right thing, but often it does either not use the full alphabet or returns characters that are not in this alphabet.

Take BCrypt for example, this is a good hash algorithm for passwords (SHA-512 is not appropriate because it is too fast), it accepts all characters of a base64-encoded string except the '+' character. On the other side it accepts '.' characters that are not part of a base64-encoded string.

PHP 5.5 will have the functions password_hash() and password_verify() ready, to make the usage of BCrypt easier, i really can recommend them. There is also a compatibility pack available for older PHP versions, on line 121 you can see that base64_encode() is indeed used, but afterwards all invalid '+' characters are replaced with allowed '.' characters:

Encoding a salt for BCrypt:

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



回答2:


BASE64 is used to encode binary data into text representation. It allow to transfer binary data using text channels. If you want to store hashed password in DB you don't have to encode it - it is already in text format.



来源:https://stackoverflow.com/questions/14648244/do-i-need-base64-encode-my-salt-for-hashing-passwords

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!