我有一个新的PHP工作任务,但我不明白是否可以解决。任务:
You need to create PHP web page that implements functional on picture below. Data must be stored in SQL. Hacker can not see user phone numbers and emails even if he got access to database or files. The solutions must contain standart PHP libs.
那么,我应该使用什么算法来解决问题?我可以存储具有password_hash()
功能的电子邮件,当我需要从电子邮件中检索电话号码时,我会使用password_verify()
查看是否存在电子邮件。但是,如果我需要发送纯电话和未发送的电话号码怎么办?
答案 0 :(得分:3)
PHP提供内置solutions来加密和解密数据。使用例如MCrypt,支持通用算法的良好自助餐。您选择的确切cipher由您决定,具体取决于所需的安全级别。请阅读Wikipedia on block ciphers了解一般情况。 修改:在PHP 7.1中了解到MCrypt为deprecated,建议使用OpenSSL代替。
如果即使黑客获得对您系统的完全访问权限,也必须无法访问电话号码,那么解密密钥显然必须是非服务器的,即。你不能将它存储在数据库或文件系统中。
在您的规范中,此密钥将是与电话号码匹配的电子邮件地址。然后,在输入时,您将单向散列电子邮件,并使用未散列的电子邮件作为加密电话号码的密钥。在请求时,您可以使用电子邮件哈希找到匹配的电话号码,并使用未填充的电子邮件作为密钥对其进行解密。应该让你排序。
更新:提取与数据库中的电话/电子邮件对匹配的记录时,如果您使用了password_hash()
(每次都会生成一个新的盐和一个唯一的字符串) ,那么你唯一的选择是获取所有记录并通过password_verify()
迭代它们。这不是特别可扩展的。
除非这是一项安全练习,否则我不确定我是否会为电子邮件打扰一个简单的sha1()
哈希值。或者使用例如crypt($email, '$2y$08$Some22CharsOfFixedSalt$');
- 请参阅crypt() - 并生成一个使用固定盐字符串的基于blowfish的哈希,从而产生不变的哈希值。然后我还会从数据库条目中截断结果字符串的前导盐部分。
如果你感觉很狡猾,为什么不做一个从每封电子邮件中获取唯一字符串的算法,然后在散列函数中使用它来代替盐,而不是使用相同的盐来散列所有电子邮件。
您还可以委派数据库的电子邮件哈希并使用MySQL's encryption functions。然后你会使用例如您SHA2('email', 256)
和INSERT
次问题中的SELECT
INSERT INTO records VALUES (SHA2('email@what', 256), 'TheEncryptedTelNo');
:SELECT * FROM records WHERE email = SHA2('email@what', 256);
和{{1}}。 (请务必注意手册对明文数据可能存储在日志中的注意事项;即在执行此操作之前了解您的MySQL设置。)