Я шифрую с использованием PHP перед сохранением зашифрованных данных в MySQL. Я убежден, что в конечном итоге это лучший способ по сравнению с использованием функций AES_ * в MySQL.
Мой вопрос сейчас заключается в том, существует ли эффективный способ поиска зашифрованных данных, кроме хранения хешированной версии данных с возможностью поиска? Например, два столбца на данные: first_name_encrypted, first_name_hashed.
$hashed_search = myhash('John');
$q = "SELECT * FROM table WHERE first_name_hashed = '$hashed_search'";
Это то, что я делаю сейчас, есть ли лучший способ?
Мой вопрос сейчас заключается в том, существует ли эффективный способ поиска зашифрованных данных, кроме хранения хешированной версии данных с возможностью поиска? Например, два столбца на данные: first_name_encrypted, first_name_hashed.
Близко, но не сигара. Увидеть: Как искать зашифрованную информацию по слепому индексу.
Один из примеров, используя библиотека аутентифицированного шифрования вместо того, чтобы просто использовать встроенный в MySQL AES_*()
функции:
$first_name_hash = hash_hmac('sha256', $firstName, $secretKey);
$stmt = $db->prepare('SELECT * FROM table WHERE first_name_idx = ?');
$result = $db->execute([$first_name_hash])
->fetch(PDO::FETCH_ASSOC);
if ($result) {
$first_name = Crypto::decrypt($result['first_name_encrypted'], $otherSecretKey);
}
Слепой индекс на основе HMAC-SHA256 предпочтительнее простого хеша.
Также: используйте аутентифицированное шифрование. Это не подлежит обсуждению.
Как правило, вы не должны шифровать данные, хранящиеся в базе данных, по которой вам нужно искать.
В приведенном вами примере было бы полезно узнать контекст, по которому вы захватываете пользователя по имени, и каковы ваши общие проблемы безопасности …
$hashed_search = myhash('John');
$q = 'SELECT * FROM table WHERE first_name_hashed = '.$hashed_search;
Является ли это веб-приложением, и вашей главной задачей является незашифрованная передача личной информации пользователя по сети? Используйте зашифрованное соединение при отправке данных между ПК пользователя и сервером (например, «https»).
Вас беспокоит, что кто-то взламывает сервер и скачивает копию базы данных? Рассмотрите возможность ограничения количества личной информации, которую вы храните. Вам действительно нужно хранить настоящее имя пользователя?
Предполагая, что вам НЕОБХОДИМО хранить личную информацию о пользователе, рассмотрите возможность использования других методов для извлечения их записей из базы данных, чем использование частей, идентифицирующих личность (т.е. не берите их по имени «first_name»). Попробуйте захватить пользователя с помощью идентификатора или имени пользователя, которое не может быть связано с его реальными именами. Это позволит вам использовать индексирование для быстрого поиска записей, и вы можете зашифровать их личную информацию (имя, фамилию, адрес электронной почты, номер телефона и т. Д.) Для вашего сердца.
Если это вам не поможет, возможно, предоставьте больше контекста о том, что вы пытаетесь достичь и почему.
TLDR: Пытаться искать зашифрованные данные — плохая идея. Подумайте, какой проблемы вы пытаетесь избежать, и придумайте альтернативное решение.