mcrypt 加密将 s 束 '%00' 添加到字符串末尾
Posted
技术标签:
【中文标题】mcrypt 加密将 s 束 \'%00\' 添加到字符串末尾【英文标题】:mcrypt encrypt adding s bunch of '%00' to end of stringmcrypt 加密将 s 束 '%00' 添加到字符串末尾 【发布时间】:2011-08-06 00:47:49 【问题描述】:使用 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() 来摆脱它们,但我想了解为什么会这样。
【问题讨论】:
恰恰相反。编辑显示。 【参考方案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 填充。实现填充的多个代码sn-ps可以在in the comments section of mcrypt_encrypt
找到。
mcrypt_encrypt
目前似乎不支持 AES 的流模式,因此如果您想保留 PHP mcrypt 库,则该选项不可用。
【讨论】:
【参考方案2】:您可以使用此方法修复它以消除填充字符:在我们的例子中,我们使用 Zend。
$filter = new Zend_Filter_Decrypt(array('adapter' => 'mcrypt'));
$filter->setVector($lpt->_seed);
str_replace("\x0", '', trim($filter->filter(base64_decode($textToDecrypt))));
【讨论】:
这看起来像是删除了所有的 0x00 字节,而不仅仅是填充的 0x00 字节。你真的应该使用rtrim($decrypted, "\0")
。【参考方案3】:
Rijndael 是block cypher,这意味着它对特定长度的数据块(在本例中为 128 位)进行操作。这意味着如果输入文本的长度不是块大小的倍数,则必须对其进行填充以适应。在这种情况下,填充为零;还有许多其他可能的padding schemes 可以使用,但是如果您希望它们与 PHP 的 mcrypt 一起使用,则必须手动应用它们。
【讨论】:
默认填充(也是mcrypt
内部唯一支持的填充)是NULL
-填充(不是0
)。 %00
是一个 URL 编码的 NULL
字符 x00
。
@SteanGehrig:“零”可能表示字符 U+0030 或字符 U+0000。
@Anomie 两者都是错误的,因为我们讨论的是具有该值的字节,而不是字符。以上是关于mcrypt 加密将 s 束 '%00' 添加到字符串末尾的主要内容,如果未能解决你的问题,请参考以下文章
如何安装 mcrypt 并将 mcrypt.h 添加到我的 C 程序文件中?