0

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 
Your Common Sense
  • 156,878
  • 40
  • 214
  • 345
  • Encryption/decryption doesn't corrupt the original file. The quality of the video does not been changed. But, more the file is big, more the time to encrypt and decrypt is big too. But, if it's an end to end encryption, it is done by the js of the webbrowser ? – svgta Jun 18 '23 at 11:25
  • In my case it did. Soon I will also add my code in question to show how I encrypted those files. By the way you said that I should use js to encrypt and decrypt files. But bro js is client side and I first verify files then upload it in my server for the verifying purpose php is best and not js. – Make Mutistico Jun 18 '23 at 11:37
  • Do you have to use PHP? I prefer c for working with binary data as it doesn't mess with your data the same way PHP does sometimes. – Simon Goater Jun 18 '23 at 12:00
  • Bro, I don't Know C at all and how it runs and even If I would learn basic syntax of C I won't lke to use it in my application at this time because I am definately gonna write a beginner level code of C in my app which is not recommended. – Make Mutistico Jun 18 '23 at 12:35
  • *And if I don't encrypt users file how would I provide end to end encryption to users.* Use TLS? If you do your own encryption, how do you get the decryption key to your users? If you send it with the file, there's no point in doing the encryption. – Andrew Henle Jun 18 '23 at 13:04
  • Well, there are certain combinations of creating key including user image names encrypted even before uploading on server and usersid in hashing algorithms and certain other parameters for keys automatically generated for each message including images. So even if I know that this is the user I can't decrypt his messages because in msg table I never save iser id instead complex hashes of users. And with TLS. Can you provide any example in a little detail. – Make Mutistico Jun 18 '23 at 13:27

0 Answers0