Я - часть команды разработчиков, которая запускает веб-приложение, которое хранит и получает HIPAA (медицинские) данные. Недавно, инструкции HIPAA были обновлены для включения политики, которая запрашивает ту всю клиентскую информацию идентификации быть зашифрованной, когда это "в покое" (сохранено в базе данных и не получаемый доступ).
Первая проблема, которой мы должны были заняться, решала, что лучший способ к двухстороннему шифрует данные способом, который делает данные безопасными в случае нарушения.
Самое быстрое решение, которое мы предложили, состояло в том, чтобы использовать mcrypt для шифрования данных, прежде чем мы вставили его в базу данных.
Приложение, которое мы разрабатываем, довольно старо (когда веб-приложения идут), и использует большое процедурное программирование, а также сильную зависимость от функции mysql_query, чтобы вставить, обновить, получить, и удалить данные. У нас нет времени или роскоши перевода нашего кода к уровню абстракции базы данных. Так, единственный способ реализовать эту систему шифрования/дешифрования состоит в том, чтобы вручную отредактировать все запросы CRUD для использования данных, это было зашифровано через mcrypt. Это очень неэффективно и чрезвычайно подвержено ошибкам.
Мы решили, что самый быстрый и самый эффективный способ решить нашу проблему состоит в том, чтобы перезаписать собственную функцию mysql_query с одним из нашего собственного изобретения. В нашей новой функции мы шифровали бы/дешифровали бы значения данных прежде, чем отправить запрос на сервер / возврат набора результатов.
Хотя вы ранее заявляли, что не можете / не хотите переводить свой код на уровень абстракции базы данных, я считаю, что это было бы идеальным решением. Конечно, сейчас работы намного больше, но она окупается. То, что вы предложили, - это хитрость, которая может (и, вероятно, приведет) к ошибкам и головной боли в будущем.
Следующим лучшим вариантом было бы зашифровать всю базу данных, как предлагается в комментариях. Существуют решения для прозрачного шифрования на разных уровнях, например: this или this
Еще одна вещь, которую вы, возможно, захотите изучить, - это встроенные в MySQL функции шифрования и дешифрования . , который можно использовать для реализации шифрования на уровне столбцов, если вас беспокоит производительность.
Хотя лучшим решением был бы уровень абстракции, предложенный другими ответами, вы можете переопределить существующие функции PHP своими собственными версиями с помощью расширения PECL Runkit
Что-то вроде:
runkit_function_rename ( 'mysql_query', 'mysql_query_old' );
function mysql_query ( $query , $link_identifier=null ) {
// modify $query here for UPDATE/DELETE statement and any WHERE clause, etc
$newQuery = modifyQuery($query);
if (is_null($link_identifier)) {
$result = mysql_query_old ( $newQuery);
} else {
$result = mysql_query_old ( $newQuery, $link_identifier);
}
// modify $result here for returned data from any SELECT statement
return modifyResult($result);
}
Примечание. По умолчанию только пользовательское пространство. функции могут быть удалены, переименованы или изменен. Чтобы отменить внутренние функции, необходимо включить настройка runkit.internal_override в php.ini.
Я бы не рекомендовал это решение. Несколько лет назад мне пришлось сделать нечто подобное в java, где было намного проще расширить jdbc; но хотя синтаксический анализ SQL-запросов достаточно сложен, он становится еще сложнее, если в ваших запросах используются переменные связывания. Остерегайтесь сбежавших струн! Следите за любым использованием связанных функций, таких как mysql_db_query, на всякий случай, если они используются вместе с mysql_query в приложении!
Приносим извинения за неустойчивый набор текста. Моя жена несколько раз подключалась к нашему маршрутизатору, пока я писал это предложение
Вы можете шифровать на уровне файловой системы, и пусть этим занимается ОС. Если вы хотите сделать это на уровне PHP, расширьте, не перезаписывайте.
function mysqle_query() {
// Do some stuff
// like replace fieldnames with AES_ENCRYPT(fieldname) on insert and delete
// and replace fieldnames with AES_DECRYPT(fieldname) on select
mysql_query();
}
Я думаю, что одним из способов автоматической обработки этого может быть изучение MySQL proxy
и реализация шифрования через него. Я играл с ним 2 или около того лет назад, когда он был на очень ранней стадии, и, насколько я помню, он мог перехватывать запросы и делать с ними "всякие штуки" :) Никаких изменений в коде, по сути, не требуется. Надеюсь, это поможет.