I am working on chat website based on php and mysql. In this application users can send audio,video and images and almost all kinds of file to each other. I am trying to add the feature of end to end encryption in it. So, for text messages I am using openssl with AES-256-CBC encryption creating keys the way that only the sender and receiver can access it. And here comes to encrypt media like large videos. I searched for 3 days on stackoverflow and read many blogs but none of them seem to solve my problem. I found this article useful in encrypting large files https://medium.com/@antoine.lame/how-to-encrypt-files-with-php-f4adead297deb but this way is only valid for encrypting small images when I tried to encrypt 640mb video with it didn't the work the way it should like sometime video loses all its quality and believe me it is thousand times worse than 144p and sometime the video lose all the frames and only audio comes and it takes more than 82 second to encrypt the video.
My main question it is that should I really encrypt users file in order to provide end to end encryption and if so how to accomplish is this by making your first priority performance. Imagine I need to load media and other files in chat and in my server I have encrypted version of it,in order to do so every time users load the page I need to decrypt those file and provide those user on the fly.
And if I don't encrypt users file how would I provide end to end encryption to users.
Any help is highly appreciated and if any genius know that how whatsapp or telegram does it in secure chat kindly answer my question and help with valuable resource. Thanks in advance.
A little humble request for stackoverflow community please do not close my question saying that it is already answer here or there because I believe it is not the same question. And technology changes everyday people and a man always need new and better answers!
<?php
define('FILE_ENCRYPTION_BLOCKS', 10000);
/**
* @param $source Path of the unencrypted file
* @param $dest Path of the encrypted file to created
* @param $key Encryption key
*/
function encryptFile($source, $dest, $key)
{
$cipher = 'aes-256-cbc';
$ivLenght = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivLenght);
$fpSource = fopen($source, 'rb');
$fpDest = fopen($dest, 'w');
fwrite($fpDest, $iv);
while (! feof($fpSource)) {
$plaintext = fread($fpSource, $ivLenght * FILE_ENCRYPTION_BLOCKS);
$ciphertext = openssl_encrypt($plaintext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
$iv = substr($ciphertext, 0, $ivLenght);
fwrite($fpDest, $ciphertext);
}
fclose($fpSource);
fclose($fpDest);
}
/**
* @param $source Path of the encrypted file
* @param $dest Path of the decrypted file
* @param $key Encryption key
*/
function decryptFile($source, $dest, $key)
{
$cipher = 'aes-256-cbc';
$ivLenght = openssl_cipher_iv_length($cipher);
$fpSource = fopen($source, 'rb');
$fpDest = fopen($dest, 'w');
$iv = fread($fpSource, $ivLenght);
while (! feof($fpSource)) {
$ciphertext = fread($fpSource, $ivLenght * (FILE_ENCRYPTION_BLOCKS + 1));
$plaintext = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv);
$iv = substr($plaintext, 0, $ivLenght);
fwrite($fpDest, $plaintext);
}
fclose($fpSource);
fclose($fpDest);
}
// encryptFile('6094273.mp4','drama.mp4','my-secret-key'); //640mb file
decryptFile('drama.mp4','new.mp4','my-secret-key'); //640mb file
// encryptFile('1.png','2.png','my-secret-key');
// decryptFile('2.png','last.png','my-secret-key');
echo memory_get_peak_usage(true)/1024;
//well code is from github