使用 phpseclib 的 Crypt_AES 类一次加密和解密文件会使文件为空


Use phpseclib's Crypt_AES class to encrypt and decrypt a file at once makes the file empty

所以我有一个脚本,它使用 phpseclib 同时对同一个文件进行加密和解密。我所做的是我从文件中读取和加密内容,然后将其写回同一个文件。然后我再次读取该文件以获取加密内容并对其进行解密,然后将解密的内容再次写回同一文件。

我期待原始文件最终保持不变。不知何故,在第二步解密加密内容时,解密的内容变为空。下面是示例代码:

$aes = new Crypt_AES();
$aes->setKey('abcdefghijklmnop');
$filename = "testfile.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
$contents = $aes->encrypt($contents);
$handle = fopen($filename, 'w');
fwrite($handle, $contents);
fclose($handle);
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
$contents = $aes->decrypt($contents);
// I checked out the error_log, the contents became empty here. 
// Shouldn't it be recovered into original content?
$handle = fopen($filename, 'w');
fwrite($handle, $contents);
fclose($handle);

奇怪的是,如果我将脚本分为两个步骤,先运行第一步,然后运行第二步,那么一切都像魅力一样工作。

我知道这个工作流程有点尴尬,我绝对可以通过在第一次读取时存储原始内容并将其用于以后的回写来绕过这个问题。只是好奇我在这里做错了什么?谢谢

问题是您正在执行多个filesize()调用。执行第一个操作后,将缓存大小。然后写入文件,然后再次对其进行filesize(),即使文件大小自上次运行以来已更改(由于 PKCS 填充),filesize()也会返回上次返回的内容。演示:

<?php
file_put_contents('demo.txt', 'zzz');
echo filesize('demo.txt') . "'r'n";
file_put_contents('demo.txt', 'zzzzzz');
echo filesize('demo.txt');

您可能会期望返回 3 和 6,不是吗?对我来说,它返回 3 和 3。

我建议使用 file_get_contents() 和 file_put_contents()。如果你必须使用 fopen 和 fgets 那么在每次调用filesize()后也要做 clearstatcache()。