2015-01-13 20 views
3

我需要在一对PHP脚本中进行对称加密和解密。我正在使用mcrypt_encrypt和crypt_decrypt。为了验证这一点,我有以下代码:来自mcrypt_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和解码是因为我是json_encoding并在Post中解码令牌。

我在做什么错?

+0

你看过那些额外的字符是什么?例如如果它们是空值,那么它们可能是通过加密添加的填充字符,以使字符串达到crypt算法要求的任何块大小。 –

+0

@MarcB对不起,我怎么知道这些角色是什么? – JeffB6688

+0

使用'ord(substr($ decrypted,32,1))'或任何偏移量。看看char的值是什么。 –

回答

8

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

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

当前的特别标准是PKCS#7填充,它增加了填充字节的1..blocksize。如果x是填充字节数,则x也是所添加字节的值。 PKCS#7填充是确定性的,即无论明文的值如何,您都可以不加键入。零填充的行为大致相同,除非明文在末尾包含零个字符。然而,对于可打印字符串(ASCII,拉丁或UTF-8)而言,情况并非如此。

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