PHP pg_unescape_bytea在不同的机器上产生不同的结果

时间:2013-04-04 14:50:24

标签: php postgresql

好的,所以这个问题与我之前提出的问题有关: 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_byteabase64_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

1 个答案:

答案 0 :(得分:0)

我的直接猜测是,在其中一台服务器上有一个旧的libpq无法正确处理bytea的十六进制编码。如果你打算使用十六进制编码bytea,你可以考虑直接在PHP中取消编码以节省你自己的工作。

显然没有更多的信息我们无法肯定地说,但PHP中的简单解决方案无论问题是在返回的字符串的开头检查\ x,如果是,请将其删除,并且然后将十六进制转换为二进制。