2015-02-06 199 views
2

我试图做一个加密/解密例程使用mcrypt但它似乎搅乱数据即时尝试加密。mcrypt搞乱数据

赫雷什的代码:

$data = 'Some important data'; 
    $key = "mycryptKey"; 
    $cipher = "rijndael-128"; 

    $encryptedData = mcrypt_encrypt($cipher, $key, $data, MCRYPT_MODE_ECB); 
    $decryptedData = mcrypt_decrypt($cipher, $key, $encryptedData, MCRYPT_MODE_ECB); 

    var_dump($data); //string 'Some important data' (length=19) 
    var_dump($encryptedData); //string '™ì{*¾xv-&n5’Œü½Ýëc®n)mSƒ7]' (length=32) 
    var_dump($decryptedData); //string 'Some important data�������������' (length=32) 

它保持在原来的字符串的末尾添加这些字符。 我在How do you Encrypt and Decrypt a PHP String?看到一个例子,但它没有工作

那就是实际测试。关键和我使用的数据在这里

编辑

我意识到,@jonhopkins意见后,认为mcrypt的被填充后$数据内容有些“\ 0”字贴一样,所以我使用'strtok'解密后清理它:

$decryptedData = \strtok(mcrypt_decrypt($cipher, $key, $encryptedData, MCRYPT_MODE_ECB), "\0"); 
var_dump($decryptedData); //string 'Some important data' (length=19) 
+2

如果我不得不猜测,我猜测加密方法会自动填充字符串。 IIRC rijndael-128要求其输入的长度为16的倍数,所以'mcrypt_encrypt'填充0到32字节,但我认为'mcrypt_decrypt'无法确定原始长度,因此它将离开这些额外的字节。 – jonhopkins 2015-02-06 03:34:46

+0

你是天才@jonhopkins!但是继承人另一个问题:如果我传递给mcrypt之前必须修改它,如何返回相同的数据? – CarlosCarucce 2015-02-06 03:50:48

+0

这是一个很好的问题,我希望我知道答案......我甚至不能100%确定发生了什么事情。但如果我能找到任何我会让你知道的。编辑:http://stackoverflow.com/q/20507050这可能会帮助 – jonhopkins 2015-02-06 03:54:39

回答

1

你在这里丢失的是填充;要加密的数据必须先补齐:

$data = pkcs7_pad($data, 16); 

同样,解密后,你需要扭转填充:使用

$decryptedData = pkcs7_unpad($decryptedData, 16); 

功能:

function pkcs7_unpad($data) 
{ 
    return substr($data, 0, -ord($data[strlen($data) - 1])); 
} 

function pkcs7_pad($data, $size) 
{ 
    $length = $size - strlen($data) % $size; 
    return $data . str_repeat(chr($length), $length); 
} 

此外,这是重要的请注意,mcrypt扩展名比较老,维护不好;我建议改用OpenSSL。完整的示例请参阅我的earlier answer