hthang369 / laravel-database-encryption
一个用于自动加密和解密 Laravel 5.5+ 中的 Eloquent 属性的包,基于配置设置。
Requires (Dev)
- codeclimate/php-test-reporter: dev-master
- orchestra/testbench: ^3.5
- phpunit/phpunit: ~6.0|~7.0
Conflicts
Replaces
This package is auto-updated.
Last update: 2024-09-17 21:28:55 UTC
README
一个用于自动加密和解密 Laravel 5.5+ 中的 Eloquent 属性的包,基于配置设置。
本项目旨在创建一个“设置后即可忘记”的包,无需太多努力即可加密和解密存储在数据库表中的 Eloquent 模型属性,实现透明化。因此,它具有强烈的观点,但旨在进行 配置。
启用后,它会自动开始在模型属性中存储数据时加密数据,并在从模型属性中检索数据时解密数据。
所有加密的数据都带有标题,以便轻松识别加密数据,轮换加密密钥,以及(可选)对加密数据格式的版本进行控制。
这支持存储加密或非加密数据的列,以便更容易进行迁移。数据可以正确地从列中读取,无论是否加密,但在将其保存回这些列时将被自动加密。即使数据库中存储的底层值由本包加密,标准 Laravel Eloquent 功能(如属性转换)也将继续按正常方式工作。
有关 laravel-database-encryption
的文档可在网上找到,源文件位于 docs/
目录中。最合理的起点是 HasEncryptedAttributes 特性的文档。
目录
要求
- Laravel: 5.5, 5.6, 5.7, 或 5.8
- PHP: 7.1, 7.2, 或 7.3
- PHP OpenSSL 扩展
状态
模式
加密值通常比明文值长,有时长得多。您可能会发现,数据库表中的列宽度需要更改才能存储此包生成的加密值。
如果您正在加密如 JSON 块的长字符串,则加密值可能会超过 VARCHAR
字段可以支持的范围,您需要将列类型更改为 TEXT
或 LONGTEXT
。
常见问题解答包含有关从 elocryptfive 迁移的迁移说明。
安装
第 1 步:Composer
通过 Composer 命令行
$ composer require austinheap/laravel-database-encryption
或将包添加到您的 composer.json
{ "require": { "austinheap/laravel-database-encryption": "^0.2" } }
第 2 步:启用包(可选)
此包实现了 Laravel 自动发现功能。安装后,将自动添加包提供者和外观。
如果您想显式声明服务提供者和/或别名,您可以首先将服务提供者添加到您的 config/app.php
文件中。
'providers' => [ // AustinHeap\Database\Encryption\EncryptionServiceProvider::class, ];
然后,将别名添加到您的 config/app.php
文件中。
'aliases' => [ // 'DatabaseEncryption' => AustinHeap\Database\EncryptionFacade::class, ];
第 3 步:配置包
发布包配置文件。
$ php artisan vendor:publish --provider="AustinHeap\Database\Encryption\EncryptionServiceProvider"
现在,您可以通过编辑 config/database-encryption.php
文件来启用 Eloquent 模型的自动加密和解密。
return [ 'enabled' => env('DB_ENCRYPTION_ENABLED', true), ];
或者,通过 Laravel 的 .env
文件或托管环境设置环境变量 DB_ENCRYPTION_ENABLED
为 true。
DB_ENCRYPTION_ENABLED=true
用法
在您希望应用加密的任何 Eloquent 模型中使用 HasEncryptedAttributes
特性,并定义一个包含要加密的属性列表的 protected $encrypted
数组。
例如:
use AustinHeap\Database\Encryption\Traits\HasEncryptedAttributes; class User extends Eloquent { use HasEncryptedAttributes; /** * The attributes that should be encrypted on save. * * @var array */ protected $encrypted = [ 'address_line_1', 'first_name', 'last_name', 'postcode' ]; }
您可以将 $casts
和 $encrypted
结合起来存储加密数组。数组首先会被转换为 JSON,然后进行加密。
例如:
use AustinHeap\Database\Encryption\Traits\HasEncryptedAttributes; class User extends Eloquent { use HasEncryptedAttributes; protected $casts = ['extended_data' => 'array']; protected $encrypted = ['extended_data']; }
通过包含 HasEncryptedAttributes
特性,Eloquent 提供的 setAttribute()
和 getAttributeFromArray()
方法被覆盖,以包括一个额外的步骤。这个额外的步骤简单地检查通过设置器/获取器访问的属性是否包含在模型上的 $encrypted
数组中,然后相应地对其进行加密或解密。
密钥和 IV
使用的密钥和加密算法是默认的 Laravel Encrypter
服务,并在 config/app.php
中配置。
'key' => env('APP_KEY', 'SomeRandomString'), 'cipher' => 'AES-256-CBC',
如果您使用 AES-256-CBC
作为加密数据的密文,如果您还没有生成应用程序密钥,可以使用内置命令 php artisan key:generate
生成。如果您正在加密较长的数据,您可能想要考虑使用 AES-256-CBC-HMAC-SHA1
密文。
加密的 IV 是随机生成的,不能设置。
单元测试
此包使用 orchestral/testbench 包构建了激进的单元测试,该包基于 PHPUnit。单元测试的执行需要一个 MySQL 服务器。
在线提供了 laravel-database-encryption 的代码覆盖率报告。
覆盖
此特性会影响以下 Laravel 5.5 的 Eloquent 方法。
constructor()
-- 调用fill()
。fill()
-- 调用setAttribute()
,该方法已被扩展以加密数据。hydrate()
-- 待定。create()
-- 调用constructor()
,因此fill()
。firstOrCreate()
-- 调用constructor()
。firstOrNew()
-- 调用constructor()
。updateOrCreate()
-- 调用fill()
。update()
-- 调用fill()
。toArray()
-- 调用attributesToArray()
。jsonSerialize()
-- 调用toArray()
。toJson()
-- 调用toArray()
。attributesToArray()
-- 调用getArrayableAttributes()
。getAttribute()
-- 调用getAttributeValue()
。getAttributeValue()
-- 调用getAttributeFromArray()
。getAttributeFromArray()
-- 调用getArrayableAttributes()
。getArrayableAttributes()
-- 扩展以解密数据。setAttribute()
-- 扩展以加密数据。getAttributes()
-- 扩展以解密数据。castAttribute()
-- 扩展以转换加密数据。isDirty()
-- 扩展以识别加密数据。
常见问题解答
我能否手动加密或解密任意数据?
是的!您可以使用 encryptedAttribute()
和 decryptedAttribute()
函数手动加密或解密数据。例如:
$user = new User(); $encryptedEmail = $user->encryptedAttribute(Input::get('email'));
我能否搜索加密数据?
不!您将无法搜索此包加密的属性,因为……它是加密的。比较加密值需要固定的 IV,这会引入安全问题。
如果您需要搜索数据,则可以:
- 让它保持未加密,或者
- 使用如
SHA256
这样的知名哈希算法对数据进行哈希处理,而不是使用加密值进行搜索。
您可以将哈希值和加密值都存储起来,使用哈希值进行搜索,并在需要时检索加密值。
我能否加密我的所有 User
模型数据?
不!搜索中的相同问题也适用于身份验证,因为身份验证需要搜索。
此软件包是否与 elocryptfive
直接兼容?
不!虽然它是一个(更现代的)替代品,但并非直接兼容。要从 elocryptfive 迁移到这个软件包,您必须
- 解密数据库中所有由 elocryptfive 加密的全部数据。
- 从您的模型/代码中删除对 elocryptfive 的任何调用。
- 从您的
composer.json
中删除 elocryptfive 并运行composer update
。 - 到此为止,您应该数据库中没有加密数据,并且所有调用/引用都已删除,但请确保已完全清除 elocryptfive。
- 按照上面的安装说明操作。
- ???
- 有利可图!
欢迎提交自动化迁移的拉取请求,但目前这超出了本项目的目标。
此包是否与 insert-random-Eloquent-package-here
兼容?
可能不是!在随机软件包之间保证互操作性不可行,尤其是那些也大量修改 Eloquent 默认行为的软件包。
不会接受有关互操作性的问题和拉取请求。
实现
以下流量相当大的网站在生产中使用此软件包
鸣谢
这是一个 delatbabel/elocryptfive 的分支,后者是 dtisgodsson/elocrypt 的分支,后者是基于早期工作的。
贡献
许可协议
MIT 许可证(MIT)。有关更多信息,请参阅 许可证文件。