繁体   English   中英

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

[英]How to prevent mcrypt_encrypt() from failing to encrypt larger file?

我正在尝试使用类似于脚本的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致命错误:在第620行的/home2/myaccount/public_html/myfldr/myfile.inc中,耗尽了134217728字节的允许内存大小(尝试分配51694736字节)

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

因此,我进行了一些研究,人们建议将以下内容添加到php.ini文件中:

memory_limit = -1

我做到了,但仍然得到了相同的结果。

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

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

  2. 有什么方法可以使该函数返回错误,或者引发我可以捕获的异常,而不仅仅是终止(并导致向用户显示白页/空白页)?

我还需要解决上面的第2项,以便能够在加密失败的情况下从服务器上删除未加密的文件(如果mcrypt_encrypt只是终止我的脚本,我显然不能这样做。

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

采用

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目录中,但是并非所有面板都允许这样做。

一种可能的解决方法是对文件进行小块加密(一次加密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这样做,对吗? 无论如何,请记住,它将对文件的最后一块执行此操作(除非您很幸运,以至于它已经是您块大小的倍数。

希望对您有帮助...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM