我有一个包含用户加密电子邮件地址的表。当新用户注册时,我想检查输入的电子邮件地址是否已存在于表中。我使用php中的openssl_encrypt
函数来加密每个电子邮件地址。由于函数返回不同的加密值,即使将相同的字符串作为参数传递,我也无法检查表中是否已存在电子邮件地址。什么是加密和的可行但安全的方法,检查表中是否存在电子邮件地址?
答案 0 :(得分:0)
在这里回答:Indexing Encrypted Information在我们关于PHP中的安全数据加密的论文中:
许多公司遇到的一个不寻常的问题是,“我们如何加密数据库中的信息并仍然将其编入索引以便快速检索?”例如,如果您需要能够通过医疗保健应用程序中的社会安全号码检索患者记录。
如果您有数百万条记录,那么逐个解密每条记录以执行简单的记录查找对于应用程序和数据库服务器来说都是昂贵的。存储这样的敏感记录是不可取的(除非您喜欢向您的客户道歉并为他们提供一年的免费身份盗窃保护)。
相反,请创建此信息的盲目索引以用于索引目的。首先,加密信息并将其存储在一个字段中(例如:
ssn
)。然后,将明文的单独HMAC与另一个字段中的单独密钥(例如ssn_lookup
)一起存储,并在第二个字段上创建数据库索引。 (这个想法是在MSDN blog post by Raul Garcia中提出的。如果你正在开发这个问题的.NET / SQL Server解决方案,Raul的博客文章可能更相关。)用于HMAC索引目的的密钥应仅适用于需要查询数据库的应用程序服务器,该应用程序服务器应位于单独的硬件上,并且永远不会检入版本控制。
请注意,这只允许精确搜索,而不是部分搜索。
public function getAccountByEmail($email)
{
$search = $this->pdo->prepare("SELECT * FROM table WHERE email_lookup = ?")
->execute([
hash_hmac('sha256', $email, $this->searchKeys['email'])
])
->fetchAll(\PDO::FETCH_ASSOC);
return $search;
}