richardstyles / eloquentencryption
允许使用 RSA 4096 位私钥加密和解密 Eloquent 属性。
Requires
- php: ^7.3|^8.0|^8.1
- illuminate/database: ^8.40||^9
- illuminate/support: ^8.12||^9
- phpseclib/phpseclib: ~2.0
Requires (Dev)
- orchestra/testbench: ^6.4
- phpunit/phpunit: ^8.5.19|^9.5.8
This package is auto-updated.
Last update: 2024-09-20 10:17:35 UTC
README
此包在处理敏感数据时提供了额外的安全层。允许数据库中 Eloquent 模型的键字段在存储时加密。
介绍
此开源包满足在数据库中加密所选模型数据的同时允许您旋转应用程序密钥的需求。当需要存储私有细节时,此包提供的安全性比默认的 Laravel 加密器更高。它使用默认的 4096 位 RSA 密钥安全地加密您的数据,并使用 Laravel 模型转换来动态加密和解密键字段。
通常,您会使用 Laravel 的 Encrypter 加密数据,但这具有使用 app:key
作为私有秘密的限制。由于应用程序密钥还保护会话/cookie 数据,因此建议您定期轮换此密钥 - 如果您使用此方法存储加密数据,则必须首先解密所有数据,并在执行此操作时重新加密。因此,此包通过创建一个独立且更强的加密过程来改进这一点,允许您轮换应用程序密钥。这允许在您的 Laravel 应用程序和数据库中为敏感模型数据提供一定级别的安全性。
如果您不想使用 RSA 密钥,那么我还有一个包 Eloquent AES,它使用一个单独的密钥 eloquent_key
来使用 AES-256-CBC 加密。
安装
此包需要 Laravel 8.x 或更高版本。
您可以通过 composer 安装此包
composer require richardstyles/eloquentencryption
您不需要注册 ServiceProvider,因为此包使用 Laravel 包自动发现。Migration 蓝图辅助函数通过宏添加,因此不会影响模式文件。
您可以使用此命令发布配置,如果您需要更改 RSA 密钥大小、存储路径和密钥文件名。
php artisan vendor:publish --provider="RichardStyles\EloquentEncryption\EloquentEncryptionServiceProvider" --tag="config"
为了加密和解密数据,您需要为此包生成 RSA 密钥。默认情况下,这将创建 4096 位 RSA 密钥到您的 storage/
目录。 不要将这些添加到版本控制 并相应地备份。
php artisan encrypt:generate
⚠️ 如果您重新运行此命令,您将无法访问任何加密数据 ⚠️
还有一个辅助函数来在迁移中定义您的加密字段。为此功能正常工作不需要特殊操作,只需在迁移文件中声明一个 encrypted
列类型即可。这只是在 binary
/blob
列中创建一个用于存储加密数据的列。使用此辅助函数表示在查看您的迁移时字段已加密。
Schema::create('sales_notes', function (Blueprint $table) { $table->increments('id'); $table->encrypted('private_data'); $table->encrypted('optional_private_data')->nullable(); $table->timestamps(); });
您可以使用任何其他蓝图辅助函数,例如 ->nullable()
,如果没有初始数据要加密。建议不要在这些二进制字段上放置 ->index()
,因为您不应对这些字段进行查询,因为它们是加密的。
3.x 版本使用方法
自3.x版本起,Laravel的要求是8.14。这次发布向基础Eloquent Model中添加了Model::encryptUsing()
静态函数。这使得内置的加密转换过程可以使用任何Illuminate\Contracts\Encryption\Encrypter
类。
在升级之前,请使用任何现有密钥和数据测试 否则,您可能无法按预期解密数据。如果您正在使用2.x版本,则不应看到任何问题,因为这个版本遵循了encryptUsing静态函数所需的Encrypter Contract。
在您的AppServiceProvider中
EncryptedCast::encryptUsing(new \RichardStyles\EloquentEncryption\EloquentEncryption);
然后在您的模型中,根据需要使用内置的加密转换。
class EncryptedCast extends Model { public $casts = [ 'secret' => 'encrypted', 'secret_array' => 'encrypted:array', 'secret_json' => 'encrypted:json', 'secret_object' => 'encrypted:object', 'secret_collection' => 'encrypted:collection', ]; }
这是通过PR实现的,由@hivokas对Laravel进行的修改。
2.x版本的使用
此包利用Laravel自己的自定义转换来编码/解码值。
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use RichardStyles\EloquentEncryption\Casts\Encrypted; use RichardStyles\EloquentEncryption\Casts\EncryptedInteger; use RichardStyles\EloquentEncryption\Casts\EncryptedFloat; use RichardStyles\EloquentEncryption\Casts\EncryptedCollection; use RichardStyles\EloquentEncryption\Casts\EncryptedBoolean; class SalesData extends Model { /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'private_data' => Encrypted::class, 'private_int' => EncryptedInteger::class, 'private_float' => EncryptedFloat::class, 'private_collection' => EncryptedCollection::class, 'private_boolean' => EncryptedBoolean::class, ]; }
还有额外的转换,可以将解密后的值转换为特定的数据类型。如果没有您需要的类型,只需提交一个包含足够测试的PR。
自定义RSA密钥存储
如果您想以其他方式存储RSA密钥,例如使用Hashicorp Vault。从1.4版本开始,您可以将配置选项handler
更改为使用RsaKeyHandler
合约的特定类。默认情况下,此包使用存储处理程序,将生成的密钥对保存到storage/
,并在加密或解密处理过程中检索密钥内容。这应该被考虑,因为它可能会增加应用程序的延迟。
/** * This class can be overridden to define how the RSA keys are stored, checked for * existence and returned for Encryption and Decryption. This allows for keys to * be held in secure Vaults or through another provider. */ 'handler' => \RichardStyles\EloquentEncryption\FileSystem\RsaKeyStorageHandler::class,
查询构建器
在数据库中存储加密数据的一个重大缺点是,您无法使用数据库提供者对该列进行查询。如果您需要这样做,请注意额外的开销,因为所有行都需要在集合中使用游标和延迟集合方法进行处理。
测试
composer test
变更日志
有关最近更改的更多信息,请参阅CHANGELOG。
贡献
有关详细信息,请参阅CONTRIBUTING。
支持
如果您对这个包有任何一般问题,请随时在Twitter上联系我。
如果您认为您发现了一个问题,请使用GitHub问题跟踪器报告,或者更好的是,分叉存储库并提交一个包含失败的测试的拉取请求。
如果您在使用此包,我很乐意听听您的想法。谢谢!
安全
如果您发现任何安全相关的问题,请通过电子邮件richard@udeploy.dev联系我,而不是使用问题跟踪器。
鸣谢
许可
MIT许可(MIT)。有关更多信息,请参阅许可文件。
Laravel包模板
此包是使用Laravel包模板生成的。