0

我在使用 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)失败了。似乎解密返回的值与原始数据不同。

我能做些什么来解决这个问题?

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

4

1 回答 1

0

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

解决这个问题的一种方法是去掉最后一个块的填充,如果你能可靠地找到文件的结尾。

于 2013-10-29T16:47:35.520 回答