请原谅我这个非常奇怪的问题。我理解base64编码传输数据的目的(即MIME的Base64编码),但我不知道是否需要对我的salt进行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
,假设它永远不会通过网络发送?
答案 0 :(得分:3)
每个哈希算法都需要给定字母表中的salt,这意味着使用base64_encode()
可能是正确的,但通常它不使用完整的字母表或返回不在此字母表中的字符。
以BCrypt为例,这是一个很好的密码哈希算法(SHA-512不合适,因为它太快),它接受base64编码字符串的所有字符,除了'+'字符。另一方面它接受'。'不属于base64编码字符串的字符。
PHP 5.5将准备好password_hash()
和password_verify()
函数,以便更容易地使用BCrypt,我真的可以推荐它们。还有一个compatibility pack可用于较旧的PHP版本,在第121行,您可以看到确实使用了base64_encode()
,但之后所有无效的'+'字符都被替换为允许的'。'。字符:
为BCrypt编码盐:
$salt = str_replace('+', '.', base64_encode($buffer));
答案 1 :(得分:1)
BASE64用于将二进制数据编码为文本表示。它允许使用文本通道传输二进制数据。如果要在DB中存储散列密码,则不必对其进行编码 - 它已经是文本格式。