I have been researching how to use Laravel Encryption as building a homestead encryption platform is frowned upon and rightfully so.
Illuminate\Support\Facades\Crypt::encryptString('This is a secret message from user 1 to user 2');
Take the above example, this is using my APP_KEY
which derives from my .env
file, generation previously by php artisan key:generate
. The issue is that user 1 is never issued two sets of keys to communicate only to user 2. User 3, 4 and so on could still read this message using the Illuminate\Support\Facades\Crypt::decryptString
method.
Currently, my database is set up to have a chat header. This contains information about what is communicating. All participants will use these keys for encryption and decryption - thus any outside users not being able to decrypt the messages.
public function up()
{
Schema::create('chat_headers', function(Blueprint $table) {
$table->increments('id');
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->string('private_key')->unique();
$table->string('public_key')->unique();
});
}
I also have a chat participants, this contains information about who is communicating:
public function up()
{
Schema::create('chat_participants', function(Blueprint $table) {
$table->increments('id');
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->integer('user_id')->unsigned();
# TODO: Build RBAC
$table->index(['user_id']);
$table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
});
}
Finally, I have a table for message logs. This contains the encrypted message followed by what chat room they're associating with.
public function up()
{
Schema::create('chat_messages', function(Blueprint $table) {
$table->increments('id');
$table->timestamp('created_at')->default(DB::raw('CURRENT_TIMESTAMP'));
$table->timestamp('updated_at')->default(DB::raw('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'));
$table->integer('chat_id')->unsigned();
$table->string('message');
$table->index(['chat_id']);
$table->foreign('chat_id')->references('id')->on('chat_headers')->onDelete('cascade');
});
}
How can I dynamically assign new keys to the Illuminate\Support\Facades\Crypt
to use in order to encrypt messages between a chat party?
If this is not possible, how can I secure the messages between the participants within a chat using these two keys? I feel like using Crypt
for this is 'encrypting for the sake of it' and not actually hiding the content of anything between users.
I would recommend against using the Crypt facade directly and would instead recommend using the Laravel Illuminate\Encryption\Encrypter which is the class that is used for the Crypt facade (I'm on Laravel 5.6).
Here is a little code snippet that I hope will help:
use Illuminate\Encryption\Encrypter;
//Keys and cipher used by encrypter(s)
$fromKey = base64_decode("from_key_as_a_base_64_encoded_string");
$toKey = base64_decode("to_key_as_a_base_64_encoded_string");
$cipher = "AES-256-CBC"; //or AES-128-CBC if you prefer
//Create two encrypters using different keys for each
$encrypterFrom = new Encrypter($fromKey, $cipher);
$encrypterTo = new Encrypter($toKey, $cipher);
//Decrypt a string that was encrypted using the "from" key
$decryptedFromString = $encrypterFrom->decryptString("gobbledygook=that=is=a=from=key=encrypted=string==");
//Now encrypt the decrypted string using the "to" key
$encryptedToString = $encrypterTo->encryptString($decryptedFromString);
If you would like to see the facade loading code it is in vendor\laravel\framework\src\Illuminate\Encryption\EncryptionServiceProvider.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With