【问题标题】:How can I decrypt binary data that ended with NUL characters in PHP?如何解密 PHP 中以 NUL 字符结尾的二进制数据?
【发布时间】:2013-01-16 04:56:50
【问题描述】:

例子:

$data = "Test Data\x00\x00";
echo strlen($data);

$key = "mykey";
$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, MD5($key, true), $data, MCRYPT_MODE_ECB);
echo strlen($encrypted);

$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, MD5($key, true), $encrypted, MCRYPT_MODE_ECB);
echo strlen($decrypted);

$newData = rtrim($decrypted,"\x00");
echo strlen($newData);

输出:

11
16
16
9  <-- I want 11 here

那么,有什么方法可以解密在加密之前可能已经填充了空值的数据,并取回正确长度的数据?

【问题讨论】:

  • 旁注:1) 你不应该使用 ECB 2) 你应该使用 IV 3) 你应该使用经过身份验证的加密
  • 这是与第三方的接口,所以我无法控制使用什么加密。

标签: php encryption


【解决方案1】:

发生这种情况是因为在加密时,数据需要具有一定的大小。你的数据比那个小,所以它被填充了。 PHP 用 NULL 字符填充数据,所以当您 rtrim 时,您将删除 both 您的 NULL 和 PHP 添加的那些。

一种解决方案是使用另一种方法将数据填充到正确的长度。我个人使用PKCS7 padding

这是一个如何使用这种填充方法的例子(改编自https://gist.github.com/1077723):

$data = "Test Data\x00\x00";

$key = "mykey";

$blocksize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);

// PKCS7 Padding
$pad = $blocksize - (strlen($data) % $blocksize);
$data .= str_repeat(chr($pad), $pad);

$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, MD5($key, true), $data, MCRYPT_MODE_ECB);

$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, MD5($key, true), $encrypted, MCRYPT_MODE_ECB);

// PKCS7 Padding
$strPad = ord($decrypted[strlen($decrypted)-1]);
$newData = substr($decrypted, 0, -$strPad);

演示:http://ideone.com/bMZxyf

【讨论】:

    猜你喜欢
    • 2011-07-20
    • 2020-12-14
    • 2014-02-20
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多