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

StackOverflow https://stackoverflow.com/questions/19799407

  •  04-07-2022
  •  | 
  •  

سؤال

So I have a script that uses phpseclib to do the encryption and decryption with the same file at once. What I did is I read and encrypted content from a file and wrote it back to the same file. Then I read that file again to get the encrypted content and decrypted it and wrote the decrypted content back to the same file again.

I was expecting the original file to remain unchanged in the end. Somehow, when decrypting the encrypted content at the second step, the decrypted content became empty. Below is the sample code:

$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);

The weird thing is if I divided the script into two steps and run the first step first and then run the second step everything worked like a charm.

I know this workflow is a bit awkward and I can definitely bypass the issue by storing the original content when doing the first read and use it for later write back. Just curious what I've done wrong here? Thanks

هل كانت مفيدة؟

المحلول

The problem is that you're doing multiple filesize() calls. After you do the first one the size is cached. You then write to the file and then do filesize() on it again and filesize() is returning what it returned last time even though the file size has changed since the last time it ran (due to PKCS padding). A demo:

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

You'd probably expect that to return 3 and 6 wouldn't you? For me it returns 3 and 3.

I'd recommend using file_get_contents() and file_put_contents(). If you must use fopen and fgets then do clearstatcache() as well after each filesize() call.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top