如何动态更改 Crypt 在 Laravel 中使用的密钥?

Jaq*_*arh 6 php encryption laravel laravel-5

我一直在研究如何使用Laravel 加密,因为构建宅基地加密平台是不受欢迎的,也是理所当然的。

Illuminate\Support\Facades\Crypt::encryptString('This is a secret message from user 1 to user 2');
Run Code Online (Sandbox Code Playgroud)

以上面的例子为例,这是使用APP_KEY从我的.env文件派生的 my ,以前由php artisan key:generate. 问题是用户 1 永远不会被分配两组密钥来与用户 2通信。用户 3、4 等仍然可以使用该Illuminate\Support\Facades\Crypt::decryptString方法读取此消息。

目前,我的数据库设置为具有聊天标题。这包含的信息有什么是通信。所有参与者都将使用这些密钥进行加密和解密——因此任何外部用户都无法解密消息。

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();
    });
}
Run Code Online (Sandbox Code Playgroud)

我也有一个聊天参与者,其中包含有关在通信的信息:

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');
    });
}
Run Code Online (Sandbox Code Playgroud)

最后,我有一个消息日志表。这包含加密消息,后跟他们关联的聊天室。

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');
    });
}
Run Code Online (Sandbox Code Playgroud)

如何动态分配新密钥以Illuminate\Support\Facades\Crypt用于加密聊天方之间的消息?

如果这是不可能的,我如何使用这两个密钥保护聊天中参与者之间的消息?我觉得Crypt为此使用是“为了它而加密”,而不是实际上在用户之间隐藏任何​​内容。

pwy*_*wyg 5

我建议不要直接使用 Crypt 门面,而是推荐使用 Laravel Illuminate\Encryption\Encrypter,它是用于 Crypt 门面的类(我使用的是 Laravel 5.6)。

这是一个小代码片段,我希望能有所帮助:

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);
Run Code Online (Sandbox Code Playgroud)

如果您想查看外观加载代码,它位于 vendor\laravel\framework\src\Illuminate\Encryption\EncryptionServiceProvider 中。