2016-02-04 71 views
0

我想加密访问令牌,并在某个时刻解密它。在CentOS上使用mcrypt_decrypt时出现如下奇怪的字符:

我的表的内容是这样的:

UPDATE users SET access_token = AES_ENCRYPT('adummyaccesstoken', '123456789') WHERE id = 1; 

在WAMP我的代码看起来是这样的: enter image description here

我以下列方式使用mysql的AES_ENCRYPT()的内置函数:

try{ 
    $user = "root"; 
    $pass = ""; 
    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); 
} 
catch (PDOException $e) { 
    print "Error!: " . $e->getMessage() . "<br/>"; 
    die(); 
} 

$statement = $dbh->prepare("SELECT * FROM `users` WHERE id = 1"); 
$statement->execute(); 
$row = $statement->fetch(PDO::FETCH_ASSOC); 

$row['decrypted_token'] = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, '123456789', $row['access_token'], MCRYPT_MODE_ECB)); 
var_dump($row); 

在WAMP的结果是这样的:

array (size=5) 
    'id' => string '1' (length=1) 
    'firstname' => string 'Pim' (length=3) 
    'lastname' => string 'van der Wal' (length=11) 
    'access_token' => string 'Äk„ 
vl¢Þ?ÍØ%tkѲúiLï4]«~Ô‡íW' (length=32) 
    'decrypted_token' => string 'adummyaccesstoken' (length=32) 

我对CentOS上运行的web应用程序应用了相同的方法。

$decryptToken = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, '123456789', $this->accessToken, MCRYPT_MODE_ECB)); 
echo $decryptToken; 

结果:

��m�N��kA��%+��q���/��Ĝx��ϐۊ�e �/+�d�@vU�� 

问题 我不明白为什么在这样一个奇怪的方式返回的代码。我怀疑读取解密的令牌时,这与字符集不匹配有关。

任何帮助表示赞赏。

+0

你必须使用htmlentity_encode /解码。将编码数据存储在数据库中并在解码之前在浏览器上显示 – Monty

+0

我试过'rtrim()',问题依然存在。 –

+0

类似的问题:http://forums.phpfreaks.com/topic/123592-mcrypt-decrypt-not-returning-original-string-returning-weird-data-no-errors/ –

回答

4

加密的数据是二进制的 - 它没有字符表示或编码 - 这不是文字

结果显示这里:

'access_token' => string 'Äk„ 
vl¢Þ?ÍØ%tkѲúiLï4]«~Ô‡íW' (length=32) 

大概是ISO-8895-1解释的二进制。请注意,二进制数据中的某些内容是否与回车匹配 - 这将是0A² = B2,依此类推。 如果您使用Windows控制台或在记事本中打开文件,您会看到此内容。

您在CentOS上看到的结果可能是因为您的终端或编辑器配置为UTF-8。发送到终端的任何字节都被解释为UTF-8。在UTF-8中,大多数7F以上的字节将需要匹配的替代字节,这是一个接近随机的字符串不会产生的,因此被替换的字符。

当您在数据库中存储二进制数据时,请确保您的令牌字段是blob而不是varchar。使用varchar会导致文本字符转换问题。

总之,你不需要担心底层数据是相同的。

+0

超级!我在phpmyadmin中将列类型更改为blob,并且它工作正常! –

+0

'VARBINARY'也能做到这一点。 –

+0

虽然我不得不提一件事。在更改表后,让它工作,'UPDATE'查询必须再次执行一次。 –

1

而是由blob类型设置为访问令牌列,你可以仍然使用VARCHAR但组合与base64_encode()/base64_decode()修改表的。

请看看这段代码:

//Scenario: encrypting 
//The value of $encryptedToken needs to be stored in the db 
$encryptedToken = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, 'akey', 'anaccesstoken', MCRYPT_MODE_ECB)); 

//Scenario: decryption 
$decryptedToken = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($accessToken), MCRYPT_MODE_ECB));