hamichen / laminas-doctrine-encrypt
在 Laminas 中使用时,为 Doctrine 实体提供属性加密和哈希处理
Requires
- php: ~7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.*
- ext-sodium: *
- doctrine/annotations: ^1.6
- doctrine/doctrine-module: ^4.1.1 || ^5.1 || ^6.1
- doctrine/orm: ^2.6
- laminas/laminas-dependency-plugin: ^2.5.0
- laminas/laminas-modulemanager: ^2.8
- laminas/laminas-servicemanager: ^2.7.8 || ^3.3
- laminas/laminas-stdlib: ^3.2
- paragonie/halite: ^4.4
- paragonie/hidden-string: ^1.0
This package is not auto-updated.
Last update: 2024-09-18 07:45:31 UTC
README
提供 Laminas & Doctrine 2 加密模块。支持 Mezzio。
安装
composer require somecoding/laminas-doctrine-encrypt
要求
- PHP 7.2 或更高版本(必须启用 Sodium 扩展)
如果你在 Windows 上使用 Xampp,PHP 7.2 安装可能不会自动启用 Sodium 扩展。如果是这种情况,你会得到一个错误('This is not implemented, as it is not possible to securely wipe memory from PHP')。通过在 php.ini
文件中添加以下内容来为 PHP 启用 Sodium:
extension = C:\xampp\php\ext\php_sodium.dll
这也许也适用于其他本地安装。
配置
Zend Framework / Laminas
确保将模块添加到你的应用程序配置中。在你的 modules.config.php
文件中,确保包含 Keet\\Encrypt
。
附加
使用的配置使用别名,例如 hashing_service
和 encryption_adapter
。你可以用自己的配置覆盖这些,以实现自己的 Service 和/或 Adapter 类。如果实现了正确的接口类,这些将自动由本模块使用。不过,在这样做之前,请务必阅读代码。
模块
提供了 *.dist
文件。将这些文件(删除扩展名)复制到你的应用程序中,并填写所需的关键/盐值。如果填写了这些值,它将使用 Halite 进行加密。
然而,必须指出,在撰写本 ReadMe 时,Halite 模块包含重复的 const
声明,因此你必须在你的 PHP 配置中禁用 E_NOTICE
警告:
Mezzio
当使用 Mezzio 时,你希望将 ConfigProvider 添加到你的 config/config.php
文件中。
\Keet\Encrypt\ConfigProvider::class,
当声明你的实体路径(可能是包含 App\ConfigProvider
的文件)时,请确保将路径作为数组传递。
'my_entity' => [
'class' => AnnotationDriver::class,
'cache' => 'array',
'paths' => [ __DIR__ . '/Entity' ],
],
注解示例
加密
简单,假设你有一个 Address
实体,根据 EU GDPR 规则,地址的部分,如街道,需要加密。这使用了配置默认所需的关键和盐。
要加密街道名称,请添加 @Encrypted
如下所示:
/**
* @var string
* @ORM\Column(name="street", type="text", nullable=true)
* @Encrypted
*/
protected $street;
默认情况下,加密服务假设要加密的数据是 string
类型。但是,你可能需要加密其他类型的数据,如门牌号。支持非字符串类型,但如果数据不是字符串,则必须提供数据类型。你可以这样做:
/**
* @var int
* @ORM\Column(name="house_number", type="text", nullable=false)
* @Encrypted(type="int")
*/
protected $houseNumber;
支持的类型在此处找到 https://php.ac.cn/settype。
密文表示
密文始终是长度可变且总是超过 255 个字符的字符串。因此,你应该使用能够表示其完整长度的数据类型。请注意,任何非字符串属性都将作为字符串表示在数据库中处理。
哈希
假设你想存储一个密码,它的工作方式与上面的类似。然而,这是一种不应该被解密的数据(并且没有必要解密),因此你应该对其进行哈希处理。
要哈希某些内容,如密码,请添加 @Hashed
注解。下面是示例。
/**
* @var string
* @ORM\Column(name="password", type="text", nullable=false)
* @Hashed
*/
protected $password;
注意:与 @Encrypted
不同,没有提供类型选项。因为我们无法解密数据(它是一向的),所以不需要知道原始类型是什么。响应将始终是字符串值。
控制器示例
哈希
提供了一个 HashingService
。此服务也使用 HashingAdapter
,但提供了可以在控制器和其他类(如插件)中使用的功能。该服务以别名 'hashing_service' 注册。您可以在自己的项目中覆盖 'hasing_service' 以提供自己的实现。
HashingService
提供了哈希和验证字符串的能力。这两个操作是独立的,其中一个将字符串进行单向哈希。另一个执行相同的操作(需要哈希字符串)并验证两个字符串是否完全相同(从而进行验证)。
在控制器中,要哈希一个字符串,只需这样做
$secret = $this->getHashingService()->hash('correct horse battery staple');
为了验证您下一次处理的是相同的字符串,例如在登录时比较密码,请这样做
$verified = $this->getHashingService()->verify('correct horse battery staple', $secret);
$verified
将被设置为布尔值。
为了不存储任何超过必要的数据,您可以直接从表单数据中进行比较,如下所示
if($form->isValid() && $this->getHashingService()->verify($form->getData()['password_field'], $user->getPassword()) {
// do other things
}
加密
还提供了一个 EncryptionService
,其工作方式与 HashingService
类似。它提供了加密和解密数据的功能。
要加密数据,请这样做
$encrypted = $this->getEncryptionService()->encrypt('correct horse battery staple');
要解密数据,请这样做
$decrypted = $this->getEncryptionService()->decrypt($string);