为什么使用mcrypt的文件加密失败?

时间:2013-10-03 17:37:45

标签: php encryption aes mcrypt

我使用mcrypt将文件系统上的文件加密到例如将其存储到Mysql数据库中。我已将问题简化为以下代码行:

<?php
$key = vzc_generateKey();

$file_content = file_get_contents("test.pdf"); // Fails
$file_content = file_get_contents("test2.docx"); // Fails
//$file_content = "12323"; // Works great

$hash_start = md5($file_content);

$encrypt = vzc_encryptV3($file_content, $key);

$decrypt = vzc_decryptV3($encrypt, $key);

$hash_end = md5($decrypt);

echo ($hash_end == $hash_start)."##";

function vzc_generateKey()
{
    $cstrong = false;

    while ($cstrong == false)
    {
        $bytes = openssl_random_pseudo_bytes(16, $cstrong);
    }

    return bin2hex($bytes);
}

function vzc_decryptV3($crypt,$key) {

    $content = base64_decode($crypt['crypt']);
    $iv = $crypt['iv'];

    $rijndael = 'rijndael-256';

    $cp = mcrypt_module_open($rijndael, '', 'ofb', '');

    $ks = mcrypt_enc_get_key_size($cp);

    $key = substr(md5($key), 0, $ks);

    mcrypt_generic_init($cp, $key, $iv);

    $decrypted = mdecrypt_generic($cp, $content);

    mcrypt_generic_deinit($cp);

    mcrypt_module_close($cp);

    return trim(base64_decode($decrypted));

}

function vzc_encryptV3($file_content,$key) {

    $content = base64_encode($file_content);

    $rijndael = 'rijndael-256';

    $cp = mcrypt_module_open($rijndael, '', 'ofb', '');

    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cp), MCRYPT_RAND);
    else
        $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cp), MCRYPT_DEV_RANDOM);

    $ks = mcrypt_enc_get_key_size($cp);

    $key = substr(md5($key), 0, $ks);

    mcrypt_generic_init($cp, $key, $iv);

    $encrypted = mcrypt_generic($cp, $content);

    $returnvalue = array("crypt"=>trim(base64_encode($encrypted)), "iv"=>$iv);

    mcrypt_generic_deinit($cp);

    mcrypt_module_close($cp);

    return $returnvalue;

}

?>

使用字符串“12323”一切正常,两个哈希都相同。但是这两个测试文件(一个pdf和一个docx)失败了。似乎解密返回的值与原始数据不同。

我该怎么做才能解决这个问题?

非常感谢您提供的任何提示。

1 个答案:

答案 0 :(得分:0)

这可能是文件不完全是n * blocksize的事实。这导致算法使用'\ 0'填充文件的末尾,这会在您执行md5计算时更改文件的内容。

如果能够可靠地找到文件的末尾,解决这个问题的方法就是从最后一个块中剥离填充。