0

I'm trying to make a program where people can chat and I want to encrypt the messages that are being sent. I have 2 scripts for this, one is sendtext.php and another getchat.php.

So my question is how can I encrypt the text that's being sent in one file and then decrypt the messages that will be sent back which is in another file.

So far I have the encryption working but I dont know how to decrypt in the other file. Also if you know a more secure way of doing this it would be appreciated.

sendtext.php

    $username = $_POST["name"];
    $text = $_POST["message"];

    $key = openssl_random_pseudo_bytes(32, $cstrong);
    $cipher = "aes-128-gcm";

    if (in_array($cipher, openssl_get_cipher_methods()))
    {
        $ivlen = openssl_cipher_iv_length($cipher);
        $iv = openssl_random_pseudo_bytes($ivlen);
        $ciphertext = openssl_encrypt($text, $cipher, $key, $options=0, $iv, $tag);

        echo "Encrytped: " . $ciphertext;

        //store $cipher, $iv, and $tag for decryption later
        //$original_text = openssl_decrypt($ciphertext, $cipher, $key, $options=0, $iv, $tag);
        //echo $original_text."\n";
    }

    //Add text to the table
    $inserttextquery = "INSERT INTO ".$username." (username, message) 
                        VALUES ('$username', '$ciphertext');";
    mysqli_query($con, $inserttextquery) or die("#: send text failed");

getchat.php

$username = $_POST["name"];

    $sql = "SELECT username, message FROM ".$username."";
    $result = $con->query($sql);

    if ($result->num_rows > 0)
    {
        // output data of each row
        while($row = $result->fetch_assoc()) {
            echo $row["username"] . "\t" . $row["message"] . "\t";
        }
    } 
  • 2
    You should rather have a read on https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php – maio290 Apr 10 '20 at 12:59
  • 4
    This code is wide open to SQL injection attacks and *will be hacked* if it hasn't been already. Encryption is the least of your worries. – Brad Apr 10 '20 at 13:01
  • 2
    You have a table for every user? You should not build a DB like this. It will be mess quickly. Have a `users` table and store all users there. Then userid (an autoincrementing column) in other tables. – user3783243 Apr 10 '20 at 13:08
  • @user3783243 Could you elaborate on that a bit? I have a table with all users (with the id auto increment and all). And yes I have per user a table to store their chats in another database (called userchats). How could I make it better? – Nor Alexanian Apr 10 '20 at 13:55
  • 1
    Have a `users` table in there have `userid, username, hashedpass, etc` have `userid` autoincrement so you don't run into race cases/conflicts. Then you can just do something like `select ... from messages where userid = ?` and you will get back all messages for one user. The way you currently are going will have data scattered across thousands of tables... indexing text also is more costly than integers. – user3783243 Apr 10 '20 at 13:59
  • Duplicate of https://stackoverflow.com/questions/61139298/php-how-to-encrypt-data-in-one-script-and-then-decrypt-in-another – Dharman Apr 10 '20 at 23:10

1 Answers1

0

I wrote this encryption/decryption class awhile ago:

<?php
class Cryptography
{
    private static $secret_key = 'gsdgsg423b523b5432bjbjm24vbjn2hv';
    const CIPHER_16 = 'AES-128-CBC';
    const CIPHER_32 = 'AES-256-CBC';
    public static function encrypt($str, $cl = 32)
    {
        return static::encyptedDecypted('encrypt', $str, $cl);
    }
    public static function decrypt($str, $cl = 32)
    {
        return static::encyptedDecypted('decrypt', $str, $cl);
    }
    public static function encyptedDecypted($action, $str, $cl)
    {
        $cl = (int) $cl;
        if ($cl === 16) {
            $cipher = static::CIPHER_16;
            $length = 16;
        } elseif ($cl === 32) {
            $cipher = static::CIPHER_32;
            $length = 32;
        } else {
            throw new Exception('Error Processing Request', 1);
        }
        $iv = $iv = substr(hash('sha256', static:: $secret_key), 0, 16);
        $key = hash('sha512', static::$secret_key);
        if ($action == 'encrypt') {
            $output = openssl_encrypt($str, $cipher, $key, 0, $iv);
            $output = base64_encode($output);
            $output = static::securesalts($length).$output.static::securesalts($length);
        } elseif ($action == 'decrypt') {
            $str = $text = substr($str, $length, -$length);
            $output = openssl_decrypt(base64_decode($str), $cipher, $key, 0, $iv);
        }
        return $output;
    }
    private static function securesalts($length)
    {
        if (is_int($length) && $length >= 5) {
            $chars = array_merge(range(0, 9), range('a', 'z'), range('A', 'Z'));
            $stringlength = count($chars); //Used Count because its array now
            $randomString = '';
            for ($i = 0; $i < $length; $i++) {
                $randomString .= $chars[rand(0, $stringlength - 1)];
            }
            return $randomString;
        } else {
            return false;
        }
    }
}

Use it like this:

$str = "Simple String";

//for encryption
$encrypted = Cryptography::encrypt($str);

//for decryption
$decrypted = Cryptography::decrypt($encrypted);

Don't forget to change the $secret_key ;)

  • 1
    Thank you so much! Ill give it a try :) is it open to SQL Injection attacks? – Nor Alexanian Apr 10 '20 at 13:58
  • 2
    @NorAlexanian This has nothing to do with SQL. It just encrypts/decrypts a string. How you interact with SQL is what opens you to injections. Don't put variables in SQL, parameterize and bind. – user3783243 Apr 10 '20 at 14:00
  • 1
    @NorAlexanian this class has nothing to do with SQL, you use it to decrypt/encrypt a string. others have already pointed out what you were doing wrong regarding SQL, so I thought I should answer your real question instead. If you think my answer solved it, mark it as correct! otherwise, it's your choice. – Fahad Maqsood Qazi Apr 10 '20 at 17:00
  • 3
    Yes it worked, thank you! and yeah I looked into the sql thing and will be fixing that – Nor Alexanian Apr 11 '20 at 12:16