使用phpseclib解密PHP中的大文件

时间:2014-07-29 01:51:18

标签: php aes phpseclib

我正在尝试编写一个用phpseclib动态解密AES文件的程序。 文件很大,如果我使用file_get_contents($ f)或fread(filesize($ f))来读取输入文件,我会出现内存不足错误。

出于某种原因,像这样的循环会创建损坏的输出文件。为什么!? =(

例如,大小为296,155,408字节的输入文件出现了18,805,826字节。注意:如果可以在循环的一次迭代中读取整个文件,则它可以工作。

define('MY_BUFFER_SIZE', 128 * 1024);
$sessionKey = '....';

$filenameIn = $argv[1];
$fileIn = fopen($filenameIn, 'rb');
$filenameOut = dirname($argv[1]) . DIRECTORY_SEPARATOR . basename($argv[1], '.tar.gz') . '-decrypted.tar.gz';
$fileOut = fopen($filenameOut, 'wb');

// Setup cipher for continuous buffering and copy between files.
$aesCipher = new Crypt_AES(CRYPT_AES_MODE_CBC);
$aesCipher->setKey($sessionKey);
$aesCipher->setIV("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
$aesCipher->enableContinuousBuffer();
while (!feof($fileIn)) {
    $packet = fread($fileIn, MY_BUFFER_SIZE); // @TODO: Streaming not working.
    fwrite($fileOut, $aesCipher->decrypt($packet));
}

fclose($fileIn);
fclose($fileOut);

1 个答案:

答案 0 :(得分:1)

感谢@neubert! 需要的是添加:

$aesCipher->disablePadding()

这有效:

// Setup cipher for continuous buffering and copy between files.
$aesCipher = new Crypt_AES(CRYPT_AES_MODE_CBC);
$aesCipher->setKey($sessionKey);
$aesCipher->setIV("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");
$aesCipher->enableContinuousBuffer();
$aesCipher->disablePadding();
while (!feof($fileIn)) {
    fwrite($fileOut, $aesCipher->decrypt(fread($fileIn, MY_BUFFER_SIZE)));
}