Могу ли я сохранить хешированный номер телефона и отправить его без хэша на электронную почту?

У меня есть задание для моей новой работы 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() чтобы узнать, существует ли электронная почта. Но как быть с номером телефона, если мне нужно отправить его чистым и невредимым?

1 ответ

Решение

PHP предоставляет встроенные решения для шифрования и дешифрования данных. Используйте, например, MCrypt, поддерживает хороший набор общих алгоритмов. Какой именно шифр вы выберете, зависит от вас, в зависимости от требуемого уровня безопасности. Читайте в Википедии о блочных шифрах для общей картины. Редактировать: только что узнал, что MCrypt устарела в PHP 7.1 и рекомендуется использовать OpenSSL вместо него.

Если телефонные номера должны быть недоступны, даже если хакер получает полный доступ к вашей системе, тогда ключ дешифрования, очевидно, должен быть вне сервера, т.е. Вы не можете хранить его в БД или файловой системе.

В вашей спецификации этот ключ будет тогда адресом электронной почты, который соответствует номеру телефона. Затем, во время ввода, вы односторонне хешируете электронную почту и используете нешифрованную электронную почту в качестве ключа для шифрования телефонного номера. Во время запроса вы найдете соответствующий номер телефона, используя хэш электронной почты, и расшифруете его, используя в качестве ключа не хэш-адрес электронной почты. Должны быть вы отсортированы.


Обновление: при получении записи, которая соответствует паре телефон / адрес электронной почты в базе данных, если вы использовали password_hash() (который генерирует новую соль и уникальную строку каждый раз), тогда ваш единственный вариант - извлечь все записи и выполнить их итерацию password_verify(), Это не особенно масштабируемо.

Если это не упражнение в безопасности, я не уверен, что буду беспокоиться больше, чем просто sha1() хеш для электронных писем. Или используйте, например, crypt($email, '$2y$08$Some22CharsOfFixedSalt$'); - увидеть crypt () - и сгенерировать основанный на blowfish хеш, который использует фиксированную строку соли, что приводит к инвариантному хешу. Затем я бы также обрезал начальную солт-часть результирующей строки из записи базы данных.

Если вы чувствуете себя хитро, почему бы не создать алгоритм, который выводит уникальную строку из каждого электронного письма, а затем использовать его для соли в своей функции хеширования, вместо того, чтобы использовать ту же соль для хэширования всех электронных писем.

Вы также можете делегировать хеширование электронной почты для базы данных и использовать функции шифрования MySQL. Тогда вы бы использовали, например, SHA2('email', 256) в вашем INSERT а также SELECT запросы, вот так: INSERT INTO records VALUES (SHA2('email@what', 256), 'TheEncryptedTelNo'); а также SELECT * FROM records WHERE email = SHA2('email@what', 256);, (Обязательно обратите внимание на предостережение руководства в отношении данных в незашифрованном виде, которые могут храниться в журналах; т. Е. Перед установкой узнайте настройки MySQL.)

Другие вопросы по тегам