如何防止mcrypt_encrypt()无法加密更大的文件?

时间:2015-01-30 07:07:20

标签: php encryption error-log php-ini

我正在尝试使用类似于this one的PHP脚本加密上传的文件。它适用于较小的文件,但是当我尝试上传一个49.2 MB大小的测试文件时(按照今天的标准来说这不是那么大),以下内容会导致我的php页面通过终止脚本来显示空白页面:

$binaryFileData = file_get_contents($serverFilePath);
$binaryEncFile = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $binaryKey, $binaryFileData, MCRYPT_MODE_CBC, $binaryIV);

我在error_log文件中找到了一行:

  

PHP致命错误:允许的内存大小为134217728字节   (试图分配51694736字节)   第620行/home2/myaccount/public_html/myfldr/myfile.inc

在上面的示例中,第620行指向mcrypt_encrypt

所以我做了一些研究,人们建议在php.ini文件中添加以下内容:

memory_limit = -1

我做了哪些,但结果仍然相同。

所以我有一个由两部分组成的问题:

  1. 显然,如何防止该异常终止我的脚本?

  2. 有没有办法让该函数返回错误,或抛出一个我可以捕获的异常,而不是仅仅终止(并导致显示给用户的白/空白页?)

    < / LI>

    我还需要解决上面的第2项,以便在加密失败时从服务器上删除未加密的文件(如果mcrypt_encrypt只是终止我的脚本,我显然无法做到这一点。

    PS。我需要说我在使用BlueHost托管的共享帐户上运行此脚本。

2 个答案:

答案 0 :(得分:1)

使用

ini_set(“memory_limit”,”640M“);

将内存限制设置为更高的限制。 以上将此限制从128MB增加到640Mb。

如果您仍遇到问题,请使用

realpath_cache_size = 16k
realpath_cache_ttl = 120

请注意,在php 5.3中,您只需将user.ini文件(行memory_limit = 640M)放在public_html目录中,但所有cpanel都不允许这样做。

答案 1 :(得分:0)

一种可能的解决方法是以小块加密文件(一次加密4128字节)。

示例代码:

$fr=fopen('input.file','r');
$fw=fopen('output.file','w');
while(!feof($fr))
{
    $buffer=fread($fr,4128);
    $result=mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $binaryKey, $buffer, MCRYPT_MODE_CBC, $binaryIV);
    false!==$result && fwrite($fw,$result);
}
fclose($fw);
fclose($fr);

这样你最终得到一个加密文件,以后可以通过颠倒这些步骤来解密。

请注意,块大小4128不是随机选择的。知道RIJNDAEL支持128/192/256位的块(即16/24/32字节)我确定了这些数字之间的LCM(即96)然后我选择了96的倍数的任何块大小(大约4K)碰巧4128符合标准。

为什么块大小很重要?因为MCrypt将输入文本划分为块大小长度的固定块,如果有提醒,则用零填充该空格,直到块长度完全分开。所以我们不想让MCrypt这样做,对吧?无论如何,请记住它会对你文件的最后一个块这样做(除非你很幸运,它已经是你的块大小的多个。

我希望它有所帮助...