如何在加密字段上使用 UniqueEntity 约束?

Posted

技术标签:

【中文标题】如何在加密字段上使用 UniqueEntity 约束?【英文标题】:How to use UniqueEntity constraint on an encrypted field? 【发布时间】:2022-01-19 14:08:11 【问题描述】:

我正在开发一个基于 Symfony 4 的项目。我试图让 @UniqueEntity@Encrypted 字段上工作,但我不知道如何操作。

没有@Encrypted 注释,@UniqueEntity 注释可以防止重复 使用@Encrypted 注释,@UniqueEntity 注释允许复制
/**
 * @ORM\Entity(repositoryClass="App\Repository\DemoRepository")
 * @ORM\HasLifecycleCallbacks()
 * @UniqueEntity(
 *      fields="example",
 *      ignoreNull=true,
 * )
 *
 */
class Demo implements LoggableEntityInterface

    /**
     * @ORM\Column(type="text", nullable=true)
     * @Encrypted
     */
    private $example;

【问题讨论】:

在任何情况下,如果该字段实际上是加密的,Symfony 可能更难以检查是否没有任何其他具有相同值的字段。 https://packagist.org/packages/michaeldegroot/doctrine-encrypt-bundle 是的,这是我的问题 :) 这是我找到的加密数据库中字段(如电子邮件等)的解决方案。如果您有任何建议,我可以尝试其他方法。 不知道那个包是如何工作的。但是拥有一个唯一的字段并对其进行加密并没有多大意义。如果您想在不破坏加密的情况下检查字段是否唯一,您可能希望将哈希存储在不同的字段中。 假设我正在添加一个新用户。我不想存储未加密的用户电子邮件,同时我想避免电子邮件重复。你会怎么做? 我不想存储未加密的用户电子邮件”您介意在您的用例中提供一些上下文,其中电子邮件地址被视为如此您是否需要在 RDBMS 所做的任何静态加密的基础上对它们进行加密?我曾在一些非常敏感的环境中工作过,但我从未见过在将电子邮件地址插入任何类型的数据存储之前,在应用程序级别单独选择并对其进行加密。 【参考方案1】:

首先,我不知道 Encrypted 包是如何工作的,但如果字段的内容被加密,框架可能很难或不可能检查新值是否与旧值匹配。

这取决于字段的加密方式以及检查方式。 UniqueEntity 是一个验证检查,因此在保存值之前执行。它应该首先加密该值,并与加密值进行比较。 Symfony 注释不支持该工作流。

您可以存储字段的哈希值,设置Unique 检查哈希值,而不是字段。不过,它会为您的桌子增加相当多的存储空间。

一个简单的实现:

/**
 * @ORM\Entity
 * @UniqueEntity(
 *      fields="emailHash",
 *      ignoreNull=true,
 * )
 *
 */
class Foo 

 /**
  * @ORM\Column(length="128")
  * @Encrypted
  */
  private $email;

 /**
  * @ORM\Column(length="40")
  */
  private $emailHash;

  public function getEmail(): string
  
        return $this->email; 
  

  public function setEmail(string $email)
  
        $this->email = $email;
        $this->emailHash = hash('sha1', $email . get_class($this));
  

现在将对散列进行检查,散列不会被加密,但存储起来应该相对安全。请注意,我还使用类名作为“盐”,因此哈希稍微更安全。


或者,您可以使用注释的repositoryMethod 键,并创建一个自定义存储库方法,该方法采用原始值,对其进行加密,并通过加密值执行搜索。这意味着您了解如何使用您的加密包正在使用的任何工具,因此您可以在新的存储库方法中使用它。

【讨论】:

感谢您的回答!我会玩一会儿,然后回复你:)

以上是关于如何在加密字段上使用 UniqueEntity 约束?的主要内容,如果未能解决你的问题,请参考以下文章

@UniqueEntity 自定义消息未翻译

Symfony UniqueEntity 验证消息

Symfony UniqueEntity vs UniqueConstraint vs unique=true

Symfony 4 - UniqueEntity 约束不显示消息错误

如何显示Laravel Nova中的加密字段值?

如何安全地存储加密密钥?