kwerie / laminas-doctrine-encrypt
在Laminas中使用时,为Doctrine实体提供属性加密和哈希功能
Requires
- php: ~7.2 || 8.0.* || 8.1.*
- ext-sodium: *
- doctrine/annotations: ^1.6
- doctrine/doctrine-module: ^4.1.1 || ^5.1
- doctrine/orm: ^2.6
- laminas/laminas-dependency-plugin: ^2.0.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-30 23:58:35 UTC
README
提供Laminas & Doctrine 2加密模块。支持Mezzio。
安装
composer require kwerie/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
中,确保包含Kwerie\\Encrypt
。
其他
使用的配置使用了别名,例如hashing_service
和encryption_adapter
。您可以用自己的配置覆盖它们以实现自己的服务和/或适配器类。如果实现了正确的接口类,这些类将自动由该模块使用。但是在做任何事情之前,请确保阅读代码。
模块
提供了*.dist
文件。将这些文件(删除扩展名)复制到您的应用程序中,并填写所需的密钥/盐值。如果填写了这些值,则可以使用Halite直接用于加密。
但是,必须指出,在编写此README时,Halite模块包含重复的const
声明,因此您必须在PHP配置中禁用E_NOTICE
警告 :(
Mezzio
使用Mezzio时,您需要将ConfigProvider添加到您的config/config.php
文件中。
\Kwerie\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;
支持的类型在此处找到。
密文表示
密文总是产生一个长度可变且总是大于255个字符的字符串。因此,您应使用能够表示其全部长度的数据类型。请注意,任何非字符串属性在数据库中都将被处理为其字符串表示形式。
哈希
假设您想存储密码,它的工作方式与上面的例子非常相似。但是,这是一些不应解密的数据(并且不需要解密),因此您应该使用哈希来存储。
要对某些内容进行哈希处理,例如密码,请添加@Hashed
注解。下面是示例。
/**
* @var string
* @ORM\Column(name="password", type="text", nullable=false)
* @Hashed
*/
protected $password;
注意,与@Encrypted
不同,没有提供指定类型的选项。因为我们无法解密数据(它是单向的),所以不需要知道原始类型是什么。响应始终是字符串值。
控制器示例
哈希
提供了一个HashingService
。此服务也使用HashingAdapter
,但提供了可以在控制器和其他类(如插件)中使用的功能。服务注册在别名'hashing_service'下。您可以在自己的项目中覆盖'hashing_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);