【问题标题】:Extra Characters Output From mcrypt_decryptmcrypt_decrypt 输出的额外字符
【发布时间】:2015-03-12 00:15:06
【问题描述】:

我需要一对 PHP 脚本中的对称加密和解密。我正在使用 mcrypt_encrypt 和 crypt_decrypt。为了测试这一点,我有以下代码:

$encrypted_token = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $ENCRYPTION_SECRET, $refresh_token, MCRYPT_MODE_ECB);

$encrypted_encoded_token=base64_encode($encrypted_token);
echo "\nEncrypted Token: " . $encrypted_encoded_token . "\n";

为了测试这一点,我在同一个 PHP 脚本中执行以下操作:

$decoded_refresh_token = base64_decode($encrypted_encoded_token);

$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $ENCRYPTION_SECRET, $decoded_refresh_token, MCRYPT_MODE_ECB);
echo "\nDecrypted Token After decrypt: " . $decrypted . "\n";

我的输入 $refresh_token 是一长串字符,看起来像这样(只是更长):

AQCNKTZhaWTmUl3WvHOtlkv2Vc-Ybkl24D5Zp1lZPLBraTxrr-YQhErXrI2IWWEIWk5lnBc1k

解密后的解密令牌如下所示:

AQCNKTZhaWTmUl3WvHOtlkv2Vc-Ybkl24D5Zp1lZPLBraTxrr-YQhErXrI2IWWEIWk5lnBc1k�������������������

我的 $ENCRYPTION_SECRET 长度为 32 个字符。 base64_encode和decode是因为我是json_encoding和解码post中的token。

我做错了什么?

【问题讨论】:

  • 你看过那些额外的字符是什么吗?例如如果它们是空值,那么它们可能是加密添加的填充字符,以使字符串达到加密算法要求的任何块大小。
  • @MarcB 抱歉,我怎么知道这些字符是什么?
  • 使用 ord(substr($decrypted, 32, 1)) 或任何偏移量。看看 char 的值是多少。

标签: php encryption mcrypt


【解决方案1】:

那些额外的字符确实是零值的字节。 PHP 的 mcrypt 使用 0..n - 1 零填充字节,其中 n 是块大小。换句话说,如果明文已经是块大小的倍数,那么它不会填充。否则它会填充到块大小。

现在您使用的是MCRYPT_RIJNDAEL_256,它不是 AES,而是块大小为 256 位的 Rijndael。所以添加的字节数是 0..31 字节。如果您将它们视为字符串,它们将被转换为问号或被删除,具体取决于您查看字符串的内容。在 mcrypt 的 C 库中,这可能更有意义,因为零终止了一个以 null 结尾的字符串。

如今,ad-hoc 标准是 PKCS#7 填充,它添加了 1..blocksize 的填充字节。如果x 是填充字节数,那么x 也是添加字节的值。 PKCS#7 填充是确定性的,即无论明文的值如何,您都可以随时取消填充。零填充的行为方式基本相同,除非明文末尾包含零个字符。然而,对于可打印的字符串(ASCII、拉丁文或 UTF-8),情况并非如此。

最后,要删除填充,只需执行rtrim(plaintext, "\0") 即可获得原始字符串。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-16
    • 1970-01-01
    • 1970-01-01
    • 2021-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多