6

使用 OAuth 并使用以下函数加密密钥,该函数使用我们称之为“foo”的字符串(实际上是 OAuth 令牌)

public function encrypt( $text )
{
    // add end of text delimiter
    $data = mcrypt_encrypt( MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv );
    return base64_encode( $data );
}

当我使用反函数解密它时,我最终得到:

功能:

    public function decrypt( $text )
    {
        $text = base64_decode( $text );
        return mcrypt_decrypt( MCRYPT_RIJNDAEL_128, $this->key, $text, MCRYPT_MODE_ECB, $this->iv );
    }

结果:

foo%00%00%00%00%00%00%00%00%00%00%00%00%00%00

编辑:

再看一点,我意识到它实际上是 %00 的 URL 编码,这意味着我的字符串以某种方式被空字符填充?所以我目前正在使用 trim() 来摆脱它们,但我想了解为什么会这样。

4

3 回答 3

6

Rijndael 是一个块密码,这意味着它对特定长度(在本例中为 128 位)的数据块进行操作。这意味着如果输入文本的长度不是块大小的倍数,则必须对其进行填充以适应。在这种情况下,填充为零;有许多其他可能的填充方案可以使用,但是如果您希望它们与 PHP 的 mcrypt 一起使用,则必须手动应用它们。

于 2011-04-15T03:48:25.510 回答
1

您可以使用此方法修复它以消除填充字符:在我们的示例中,我们使用 Zend。

$filter = new Zend_Filter_Decrypt(array('adapter' => 'mcrypt'));
$filter->setVector($lpt->_seed);
str_replace("\x0", '', trim($filter->filter(base64_decode($textToDecrypt))));
于 2011-05-18T13:34:53.560 回答
1

MCRYPT_MODE_ECB表示您正在使用 ECB,这是一种分组密码操作模式。分组密码可以针对分组密码操作模式或流密码操作模式进行处理。常见的分组密码模式是 ECB 和 CBC,常见的流密码模式是 CTR,也称为计数器模式操作。

MCRYPT_RIJNDAEL_128是AES的实现。AES 是 Rijndael 密码,块大小为 128 位,以及三种可能的密钥大小,128、192 和 256 位。因此,如果您使用分组密码加密模式,那么您需要将纯文本的大小分别为 128 位 - 16 个字节。当然,这给您留下了当最后一个块不是 16 字节时该怎么办的问题。

PHPmcrypt_encrypt或多或少地把这留给了用户。00如果块没有满到块大小,它会用有价值的字符填充。如果输入是字符串,这很好;您可以简单地trim00返回的字符串中删除字符。但是,如果输入是以00字符结尾的二进制数据,则该字符会丢失(当然还有从字符串的开头和结尾获取的任何其他字符)。当然,您也可以将加密字符串的长度与明文一起发送。

要获得更好的方案,您只需查看 PKCS#7 填充。用于实现填充的多个代码片段可以mcrypt_encrypt.

mcrypt_encrypt currently does not seem to support stream modes for AES, so that option is out if you want to keep with the PHP mcrypt library.

于 2014-05-03T15:44:35.857 回答