Php 我是否需要base64编码我的salt(用于哈希密码)?

Php 我是否需要base64编码我的salt(用于哈希密码)?,php,passwords,base64,salt,crypt,Php,Passwords,Base64,Salt,Crypt,请原谅我提出这个非常奇怪的问题。我理解base64编码用于传输数据的目的(即MIME的base64编码),但我不知道是否需要base64编码 我编写了一个实用程序类(实际上是一个基本抽象类): 使用Symfony\Component\Security\Core\Encoder\BasePasswordEncoder; 抽象类AbstractCryptPasswordEncoder扩展了BasePasswordEncoder { /** *@返回字符串 */ 受保护的抽象函数getSaltPref

请原谅我提出这个非常奇怪的问题。我理解base64编码用于传输数据的目的(即MIME的base64编码),但我不知道是否需要base64编码

我编写了一个实用程序类(实际上是一个基本抽象类):

使用Symfony\Component\Security\Core\Encoder\BasePasswordEncoder;
抽象类AbstractCryptPasswordEncoder扩展了BasePasswordEncoder
{
/**
*@返回字符串
*/
受保护的抽象函数getSaltPrefix();
/**
*@返回字符串
*/
受保护的抽象函数getSalt();
/**
*{@inheritardoc}
*/
公共函数encodePassword($raw,$salt=null)
{
返回crypt($raw,$this->getSaltPrefix()。$this->getSalt());
}
/**
*{@inheritardoc}
*/
公共函数isPasswordValid($encoded,$raw,$salt=null)
{
返回$encoded==crypt($raw,$encoded);
}
}
真正的实现类是:

类Sha512CryptPasswordEncoder扩展了AbstractCryptPasswordEncoder
{
/**
*@var字符串
*/
私人$rounds;
/**
*@param null | int$舍入哈希循环的数量
*/
公共函数构造($rounds=null)
{
$this->rounds=$rounds;
}
/**
*{@inheritardoc}
*/
受保护的函数getSaltPrefix()
{
返回sprintf(“$6$%s”,$this->rounds?”rounds={$this->rounds}$”:“”);
}
/**
*{@inheritardoc}
*/
受保护函数getSalt()
{
返回base64_编码(openssl_随机_伪_字节(12));
}
}

关键部分是salt生成,它将嵌入到密码中:我是否出于任何原因需要
base64_编码
(存储),假设它永远不会通过电线发送?

用于将二进制数据编码为文本表示。它允许使用文本通道传输二进制数据。如果要在DB中存储哈希密码,则不必对其进行编码,因为它已经是文本格式。

用于将二进制数据编码为文本表示形式。它允许使用文本通道传输二进制数据。如果您想在DB中存储散列密码,您不必对其进行编码-它已经是文本格式。

每个散列算法都要求在给定的字母表中使用salt,这意味着使用
base64_encode()
可能是正确的,但它通常不使用完整的字母表或返回不在此字母表中的字符

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

PHP5.5将准备好函数
password\u hash()
password\u verify()
,为了更方便地使用BCrypt,我真的可以推荐它们。对于较旧的PHP版本,还有一个可用的方法,在第121行,您可以看到确实使用了
base64_encode()
,但之后所有无效的“+”字符都被替换为允许的“.”字符:

为BCrypt编码salt:

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

每个哈希算法都希望在给定的字母表中有一个salt,这意味着使用
base64\u encode()
可能是正确的,但它通常不使用完整的字母表或返回不在此字母表中的字符

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

PHP5.5将准备好函数
password\u hash()
password\u verify()
,为了更方便地使用BCrypt,我真的可以推荐它们。对于较旧的PHP版本,还有一个可用的方法,在第121行,您可以看到确实使用了
base64_encode()
,但之后所有无效的“+”字符都被替换为允许的“.”字符:

为BCrypt编码salt:

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

请参阅此问题:但否-您不应在哈希密码上使用base64。请参阅此问题:但否-您不应在哈希密码上使用base64。+1是一个好答案。关于兼容性包的一点并不完全清楚,因此为了其他人的利益,兼容性包是一个可下载的库,它为PHP5.5
password\u xxx()
用户实现PHP5.3或PHP5.4的函数。这意味着任何当前支持的PHP版本的所有用户都可以使用新的官方PHP密码API。@SDC-谢谢你的评论,我试着让它更清楚一点。回答很好,+1。虽然河豚盐的要求对我来说非常清楚(base64编码随机字节,“+”替换),但仍然不清楚sha512盐的要求:原始字节?一些字母表?@Gremo-只是看了一下PHP源代码,没有发现关于salt的SHA-512 a标签的任何限制。代码使用
strcspn()
查找salt的终止字符“$”,这意味着salt不应包含空字符,当然也不应包含“$”字符。因此,不能使用原始字节salt和无unicode字符(它们通常包含空字节)。我不能确定,我做得很好(我不是一个C破解),所以为了安全起见,最好使用与其他算法相同的字母表,比如BCrypt。关于兼容性包的一点并不完全清楚,因此为了其他人的利益,兼容性包是一个可下载的库,它为PHP5.5
password\u xxx()
用户实现PHP5.3或PHP5.4的函数。这意味着任何当前支持的PHP版本的所有用户都可以使用新的官方PHP密码API。@SDC-谢谢你的评论,我试着让它更清楚一点。回答很好,+1。虽然