使用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()来摆脱它们,但我想了解为什么会这样。
答案 0 :(得分:6)
Rijndael是block cypher,这意味着它运行在特定长度的数据块上(在这种情况下为128位)。这意味着如果输入文本的长度不是块大小的倍数,则必须将其填充以适合。在这种情况下,填充为零;还有许多其他可能的padding schemes可以使用,但是如果你想要它们使用PHP的mcrypt,你将不得不手动应用它们。
答案 1 :(得分:1)
您可以使用此方法修复它以消除填充字符:在我们的示例中,我们使用Zend。
$filter = new Zend_Filter_Decrypt(array('adapter' => 'mcrypt'));
$filter->setVector($lpt->_seed);
str_replace("\x0", '', trim($filter->filter(base64_decode($textToDecrypt))));
答案 2 :(得分:1)
MCRYPT_MODE_ECB
表示您正在使用ECB,一种分组密码操作模式。分组密码可以用于分组密码操作模式或用于流密码操作模式。常见的分组密码模式是ECB和CBC,常见的流密码模式是CTR,更好地称为计数器模式操作。
MCRYPT_RIJNDAEL_128
是AES的实现。 AES是Rijndael密码,块大小为128位,三种可能的密钥大小,128,192和256位。因此,如果您使用分组密码加密模式,则需要将纯文本分为128位--16字节 - 每个。当然,如果最后一个块不是16个字节,这会让你有一个问题。
PHP的mcrypt_encrypt
或多或少会将此问题留给用户。如果块未满块大小,则使用00
个值填充。如果输入是一个字符串,这很好;你可以简单地trim
从返回的字符串中删除00
个字符。但是,如果输入是二进制数据,以00
字符结尾,则该字符丢失(+当然从字符串的开头和结尾取出的任何其他字符)。您也可以发送加密的字符串长度和明文。
对于更好的方案,您只需要查看PKCS#7填充。可以找到用于实现填充的多个代码片段in the comments section of mcrypt_encrypt
。
mcrypt_encrypt
目前似乎不支持AES的流模式,因此如果您想继续使用PHP mcrypt库,那么该选项就不存在了。