Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to encrypt big files with php and decrypt over commandline?

I'm writing a small script in PHP to backup my files. Before I transfer the files from the server I want to encrypt them.

I did that in previous versions of my script by using exec() and OpenSSL on my Linuxserver. Now I'm looking for a native PHP-Function to do this job, mainly for better error handling.

The thing is that my files may get big (like 20gb). Furthermore it's a must that I can use a command on my shell to decrypt the file again.

Does anyone know how to encrypt big files in PHP and then decrypt on the commandline?

I'm now using PHP's mcrypt functions to encrypt:

// IV:
$iv = mcrypt_create_iv($ivSize, MCRYPT_RAND);

// Create new random Key:
$key = openssl_random_pseudo_bytes(32);

// Encrypt:
$fileStream = fopen($file, "r");
$encFileStream = fopen($file . ".enc.data", "w");

$opts = [
    'iv'   => $iv,
    'key'  => $key,
    'mode' => 'cbc'
];
stream_filter_append($encFileStream, 'mcrypt.rijndael-256', STREAM_FILTER_WRITE, $opts);
stream_copy_to_stream($fileStream, $encFileStream);

fclose($fileStream);
fclose($encFileStream);

// Encrypt random generated key and save it:
$encryptedKey = null;
openssl_public_encrypt($key, $encryptedKey, $publickey);
file_put_contents($file . ".enc.key", $encryptedKey);

// Save Initial Vetor:
file_put_contents($file . ".enc.iv", $iv);

// Delete unencrypted file:
unlink($file);

Now to decrypt on the linux commandline I tried to use mcrypt as well. But the big problem I have with that is that I have no idea how to add the IV to mdecrypt. My command I have so far is:

mdecrypt --decrypt -m CBC -f key.key archive_hallo.tar.gz.enc.data

Which of course does not work because the IV is missing. So, does anyone know how to add the IV to my mdecrypt command?

like image 902
Matthias Dunkel Avatar asked Oct 21 '22 12:10

Matthias Dunkel


1 Answers

mdecrypt CLI tool from mcrypt_2.6.8 debian package expects the specific file format with header. Search for write_file_head function, it shows first 3 bytes of the mcrypt/mdecrypt tool format:

buf[0] = '\0';
buf[1] = 'm';
buf[2] = '\3';

Header should have special bit set, and the IV embedded into the file. It will be read here, in decrypt_general function:

if (_mcrypt_iv_is_needed(td, mode, noiv) != 0) {
   IV = read_iv(FROMF, mcrypt_enc_get_iv_size(td));
} else {
   IV = _mcrypt_calloc(1, mcrypt_enc_get_iv_size(td));
}

and read_iv is defined in extra.c as:

void *read_iv(FILE * fstream, int ivsize)
{
char *IV;
     ... // malloc 
fread(IV, 1, ivsize, fstream);
    return IV;
}

So, just check first N bytes of encrypted file (you can post them here after hexdump -C) and check for mcrypt header (0x00 'm' 0x03) and for your IV. If yes - then mdecrypt tool should get IV from file. If not - there is no support for setting IV via command-line in mdecrypt, but you can hack into sources, add new option for iv, then modify decrypt_general to read iv from option.

like image 119
osgx Avatar answered Oct 23 '22 09:10

osgx