好的,所以这个问题与我之前提出的问题有关: Storing the output of openssl_random_pseudo_bytes in Postgres using php? I get an error: invalid byte sequence for encoding “UTF8”。已经回答了,但现在我遇到了另一个问题。
我正在使用openssl_random_pseudo_bytes
生成一个salt,然后我将其添加到用户密码并散列整个内容。
然后我在salt上使用pg_escape_bytea
,以便我可以将值插入/存储到PostgreSQL数据库中。这很好用。现在要在需要时检索salt,我从数据库中获取它,并在salt上使用pg_unescape_bytea
来获取用于创建哈希密码的原始原始值。
现在我发现在另一台机器上,pg_unescape_bytea
salt值不同,即使完全相同的代码在同一个数据库中使用相同版本的PHP运行。
这怎么可能?当然,如果相同的代码正在运行,在完全相同的数据库之外,它应该是相同的吗?
在插入数据库之后,我不应该从数据库中取消盐,也许它会被转义为非转义?
或者我应该先将盐(使用pg_unescape_bytea
或base64_encode
?)转移到盐上,然后再将其与密码合并?
使用示例进行更新:
$password = 'mypassword';
$salt = openssl_random_pseudo_bytes(30);
$pepper = 'pepper';
// Perhaps I should be performing a pg_escape_bytea on the salt before doing this?
$password_hash = hash('sha512', $password . $salt . $pepper);
// Adds the user to the database
$result = $data->add($email, $password_hash, pg_escape_bytea($salt), $company_id, $role_id);
然后从数据库中获取salt:
// ...some code
// ...last step when fetching the salt from the database.
$row = pg_fetch_assoc($result, 0);
$row = pg_unescape_bytea( $row['salt'] ); // This value outputted produces different results
另外,我应该注意:
在一台机器上,未转义后的盐看起来像gobbledygook,就像非UTF字符一样,这是我在表示二进制文件时所期望的。
但在另一台机器上,未转化的盐看起来几乎与逃逸的盐相同。减去\
示例:
逃脱盐:\ x34e21
非转义盐:x34e21
版本:
PHP版本:5.3.13
PostgreSQL版本:9.1
答案 0 :(得分:0)
我的直接猜测是,在其中一台服务器上有一个旧的libpq无法正确处理bytea的十六进制编码。如果你打算使用十六进制编码bytea,你可以考虑直接在PHP中取消编码以节省你自己的工作。
显然没有更多的信息我们无法肯定地说,但PHP中的简单解决方案无论问题是在返回的字符串的开头检查\ x,如果是,请将其删除,并且然后将十六进制转换为二进制。