Перегрузка встроенной функции PHP для шифрования данных для соответствия HIPAA - PullRequest
9 голосов
/ 16 июля 2010

Справочная информация:

Я являюсь частью команды разработчиков, которая запускает веб-приложение, которое хранит и извлекает медицинские данные HIPAA.Недавно рекомендации HIPAA были обновлены и теперь включают политику, которая требует, чтобы вся идентифицирующая информация о клиентах была зашифрована, когда она «в состоянии покоя» (хранится в базе данных и не используется).

Исходная проблема

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

Первоначальное решение

Самым быстрым решением, которое мы придумали, было использование mcrypt для шифрования данных до того, как мы вставили их в базу данных.

Новая проблема

Приложение, которое мы разрабатываем, довольно старое (как и веб-приложения) и использует много процедурного программирования, а также большую поддержку функции mysql_query для вставки, обновления, извлечения и удаления данных.У нас нет времени или роскоши для перевода нашего кода на уровень базы данных абстракции.Таким образом, единственный способ реализовать эту систему шифрования / дешифрования - вручную отредактировать все запросы CRUD, чтобы использовать данные, зашифрованные с помощью mcrypt .Это очень неэффективно и чрезвычайно подвержено ошибкам.

Наше предлагаемое решение

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

Куда вы, ребята, приходите

  1. Является ли это лучшим решением для решения нашей первоначальной проблемы?
  2. Как вы собираетесь переписать существующую, основную функцию PHP?

Ответы [ 6 ]

3 голосов
/ 16 июля 2010

Хотя вы ранее заявляли, что не можете / не будете переводить свой код на уровень абстракции базы данных, я считаю, что это будет идеальным решением.Конечно, сейчас намного больше работы, но это окупается.То, что вы предложили, это хак, который может (и, вероятно, приведет) к ошибкам и головным болям в будущем.

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

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

2 голосов
/ 16 июля 2010

Хотя лучшим решением будет уровень абстракции, предложенный другими ответами, вы можете переопределить существующие функции 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 в приложении!

Извинения за шаткий набор текста. Моя жена несколько раз подпрыгивала на нашем роутере, пока я писал это предложение

1 голос
/ 18 марта 2011

Есть коммерчески доступные решения, которые помогут с шифрованием данных в покое. Вы можете проверить либо Gazzang или Packet General. Оба предлагают шифрование MySQL, чтобы помочь с соответствием HIPPA. Удачи

1 голос
/ 16 июля 2010

Я думаю, что один из способов сделать это автоматически - изучить MySQL proxy

и реализовать шифрование через это. Я играл с ним 2 или около того года назад, когда он был на очень ранних стадиях, и, насколько я помню, он мог в основном перехватывать запросы и делать с ними «мелочи» :) Никаких изменений кода по сути не требовалось. Надеюсь, это поможет.

0 голосов
/ 27 сентября 2011

Я действительно думаю, что вы смотрите на это с неправильной точки зрения.Это не проблема, которую разработчики решают путем шифрования / дешифрования данных при их сохранении и извлечении из базы данных - используйте инфраструктурное решение.

Рассмотрите аппаратное или программное шифрование всего диска, шифрование самой базы данных с помощьюфункция прозрачного шифрования данных СУБД (если она есть у конкретной СУБД) или через ОС.

См. этот документ из NIST

0 голосов
/ 16 июля 2010

Вы можете зашифровать на уровне файловой системы и позволить ОС справиться с этим.Если вы хотите обрабатывать это на уровне 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();
}
...