我是否需要base64编码盐(用于哈希密码)? [英] Do I need base64 encode my salt (for hashing passwords)?

查看:777
本文介绍了我是否需要base64编码盐(用于哈希密码)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请问这个非常奇怪的问题.我了解base64编码用于传输数据的目的(即MIME的Base64编码),但是我不知道是否需要对盐进行base64编码.

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

一个真正的实现类是:

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,假设它永远不会通过电线发送?

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?

推荐答案

每个哈希算法都希望在给定的字母中加盐,这意味着使用base64_encode()可能是正确的选择,但通常它都不使用完整的字母或返回不在此字母表中的字符.

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.

以BCrypt为例,这是一种很好的密码哈希算法(SHA-512不合适,因为它太快了,不适合使用它),它接受base64编码的字符串中的所有字符("+"字符除外).另一方面,它接受."不属于base64编码的字符串的字符.

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将准备好功能password_hash()password_verify(),以使BCrypt的使用更加容易,我真的可以推荐它们.在旧版本的PHP上,还有一个兼容性包.在第121行中,您可以看到确实使用了base64_encode(),但是之后所有无效的'+'字符都被替换为允许的'.'.字符:

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:

为BCrypt编码盐:

Encoding a salt for BCrypt:

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

这篇关于我是否需要base64编码盐(用于哈希密码)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆