jfelixstudio / aesencrypt
Laravel MySql AES 加密/解密
Requires
- php: ^7.3|^8.0
- illuminate/config: ^8.0
- illuminate/database: ^8.0
- illuminate/support: ^8.0
README
Laravel 8.x, 7.x, 6.x & 5.x MySql AES 加密/解密
基于 https://github.com/devmaster10/mysql-aes-encrypt
改进
- 通过为每个加密字段使用唯一的 IV 来提高安全性。
- 支持多种加密方法,包括:aes-256-cbc
- 使用 MySQL 会话变量防止在发生 sql 错误时输出加密密钥。
- 添加了 Laravel 6 支持
- 添加了 Laravel 7 支持
- 添加了 Laravel 8 支持(由我完成)
Laravel 5.x, 6.x, 7.x & 8.x 在 mysql 侧进行数据库加密,使用原生 mysql 函数 AES_DECRYPT 和 AES_ENCRYPT
自动加密和解密模型中签名的字段/列
可以完全使用 Eloquent/Model 的所有功能
可以在加密列中进行操作 "=>, <',' between ',' LIKE '
1. 使用 Composer 安装包
For laravel 8.x: $ composer require jfelixstudio/aesencrypt
2. 配置提供者
如果您使用的是 Laravel 5.4 或更低版本,或者加密不起作用,请在 config/app.php 中添加以下内容:
'providers' => array( JfelixStudio\AESEncrypt\Database\DatabaseServiceProviderEncrypt::class )
更新您的 Eloquent 模型
具有加密列的模型应继承自 ModelEncrypt
namespace App\Models; use JfelixStudio\AESEncrypt\Database\Eloquent\ModelEncrypt; class Person extends ModelEncrypt { /** * The attributes that are encrypted. * * @var array */ protected $fillableEncrypt = [ 'name' ]; }
创建支持加密列的表
它为 Schema 添加了新功能,您可以在迁移中使用这些功能
Schema::create('persons', function (Blueprint $table) { // here you do all columns supported by the schema builder $table->increments('id')->unsigned; $table->string('description', 250); $table ->unsignedInteger('created_by')->nullable(); $table ->unsignedInteger('updated_by')->nullable(); }); // once the table is created use a raw query to ALTER it and add the BLOB, MEDIUMBLOB or LONGBLOB DB::statement("ALTER TABLE persons ADD name MEDIUMBLOB after id");
});
在 .env 文件中设置加密设置
APP_AESENCRYPT_KEY=yourencryptedkey APP_AESENCRYPT_MODE=aes-256-cbc
有关所有可用加密方法的详细信息,请参阅 https://dev.mysqlserver.cn/doc/refman/8.0/en/server-system-variables.html#sysvar_block_encryption_mode
要发布配置文件和视图,请运行以下命令
php artisan vendor:publish --provider="JfelixStudio\AESEncrypt\AesEncryptServiceProvider"
加密现有数据
为了使用此包处理现有数据,您必须首先加密所有希望使用的现有列。
注意:如果数据库已经加密,请在执行以下查询之前确保先解密。
在更改数据之前,请始终进行备份
使用此功能最简单且最安全的方法是在更新记录时使用此 MySQL 函数
CREATE FUNCTION `aes_encrypt_string` (col blob, aeskey char(255)) RETURNS blob BEGIN SET @iv = RANDOM_BYTES(16); RETURN CONCAT(AES_ENCRYPT(col, aeskey, @iv), ".iv.",@iv); END
添加 MySQL 函数后,更新记录如下所示
SET @@SESSION.block_encryption_mode = 'aes-256-cbc'; SET @AESKEY = 'yourencryptedkey'; UPDATE your_table SET your_column = aes_encrypt_string(your_column, @AESKEY), your_column2 = aes_encrypt_string(your_column2, @AESKEY) WHERE your_column NOT LIKE '%.iv.%';
以下代码将确保只有尚未加密的数据才会被加密,如果您需要多次运行此查询,则非常有用。
如果您无法创建 MySQL 函数,可以执行以下操作,但这将使用相同的 IV 对每条记录进行加密,这会降低安全性。
SET @@SESSION.block_encryption_mode = 'aes-256-cbc'; SET @AESKEY = 'yourencryptedkey'; SET @iv = RANDOM_BYTES(16); UPDATE your_table SET your_column = CONCAT(AES_ENCRYPT(your_column, @AESKEY, @iv), ".iv.",@iv), your_column2 = CONCAT(AES_ENCRYPT(your_column2, @AESKEY, @iv), ".iv.",@iv) WHERE your_column NOT LIKE '%.iv.%';
以下代码将确保只有尚未加密的数据才会被加密,如果您需要多次运行此查询,则非常有用。
在 MySQL 中解密你的数据
如果您想使用 MySQL 查询解密数据,可以向您的 MySQL 数据库添加此函数
CREATE FUNCTION `aes_decrypt_string` (col blob, aeskey char(255)) RETURNS text BEGIN RETURN CAST(AES_DECRYPT(SUBSTRING_INDEX(col, '.iv.', 1), aeskey, SUBSTRING_INDEX(col, '.iv.', -1)) as char); END
现在,当您想解密 MySQL 数据时,可以这样做
SET @@SESSION.block_encryption_mode = 'aes-256-cbc'; SET @AESKEY = 'yourencryptedkey'; SELECT *, aes_decrypt_string(yourEncryptedColum, @AESKEY) decryptedColumn, aes_decrypt_string(yourEncryptedColum2, @AESKEY) decryptedColumn2 FROM yourtable;
或者,如果您无法或不希望使用 MySQL 函数,可以使用以下查询
SET @@SESSION.block_encryption_mode = 'aes-256-cbc'; SET @AESKEY = 'yourencryptedkey'; SELECT CAST(AES_DECRYPT(SUBSTRING_INDEX(yourEncryptedColum, '.iv.', 1), @AESKEY, SUBSTRING_INDEX(yourEncryptedColum, '.iv.', -1)) as CHAR) decrypted_column FROM yourtable WHERE yourEncryptedColum LIKE '%.iv.%';