重载本机 PHP 函数以加密数据以实现 HIPAA 合规性

发布于 2024-09-10 17:17:09 字数 851 浏览 3 评论 0原文

背景信息:

我是一个开发团队的成员,该团队运行一个存储和检索 HIPAA(医疗)数据的 Web 应用程序。最近,HIPAA 指南进行了更新,其中包含一项策略,要求所有识别客户的信息在“静态”(存储在数据库中且不被访问)时进行加密。

最初的问题

我们必须解决的第一个问题是确定对数据进行双向加密的最佳方法,以便在发生泄露时确保数据的安全。

最初的解决方案

我们想出的最快的解决方案是使用 mcrypt 来加密之前的数据 我们将其插入数据库。

新问题

我们正在开发的应用程序相当古老(与 Web 应用程序一样),并且使用了大量的过程编程以及严重依赖 mysql_query 函数插入、更新、检索和删除数据。我们没有时间或精力将代码转换为数据库抽象层。因此,实现此加密/解密系统的唯一方法是手动编辑所有 CRUD 查询以使用通过

我们提出的解决方案

我们认为解决问题最快、最有效的方法是覆盖本机 mysql_query功能与我们自己的设计之一。在我们的新函数中,我们将在将查询发送到服务器/返回结果集之前对数据值进行加密/解密。

你们进来的地方

  1. 这是解决我们最初问题的最佳解决方案吗?
  2. 如何覆盖现有的核心 PHP 函数?

Background Information:

I'm part of a team of developers that runs a web application that stores and retrieves HIPAA (medical) data. Recently, the HIPAA guidelines were updated to include a policy that requires that all identifying client information be encrypted when it is "at rest" (stored in the database and not being accessed).

The Initial Problem

The first problem we had to tackle was determining the best way to two-way encrypt the data in a manner that makes the data secure in the event of a breach.

The initial Solution

The quickest solution we came up with was to use mcrypt to encrypt the data before we inserted it into the database.

The New Problem

The application we're developing is quite old (as web applications go) and uses a lot of procedural programming as well as heavy reliance on the mysql_query function to insert, update, retrieve, and delete data. We do not have the time or luxury of translating our code to a database-abstraction-layer. So, the only way to implement this encryption/decryption system is to manually edit all of the CRUD queries to use data that's been encrypted via mcrypt. This is very inefficient and extremely error-prone.

Our Proposed Solution

We decided that the fastest and most effective way to solve our problem is to overwrite the native mysql_query function with one of our own devising. In our new function, we would encrypt/decrypt the data values before sending the query to the server/ returning the resultset.

Where You Folks Come In

  1. Is this the best solution to solving our initial problem?
  2. How do you go about overwriting an existing, core PHP function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

逐鹿 2024-09-17 17:17:09

尽管您之前说过您不能/不会将代码转换为数据库抽象层,但我相信这将是理想的解决方案。当然,现在还有很多工作要做,但这是有回报的。您提出的是一种黑客攻击,它可能(并且可能会)在未来导致错误和麻烦。

下一个最好的办法是加密整个数据库,正如评论中所建议的那样。有不同级别的透明加密解决方案,即: thisthis

您可能想要研究的另一件事是 MySQL 的本机 加密和解密函数,如果您是,可以使用它来实现列级加密关心性能。

Although you've previously stated you can't/won't translate your code into a database abstraction layer, I believe that would be the ideal solution. Sure, it's a lot more work right now, but it pays off. What you've proposed is a hack, that can (and probably will) lead to errors and headaches in the future.

The next best thing would be to encrypt the whole database, as proposed in the comments. There are solutions out there for transparent encryption in different levels, ie: this or this

Another thing you might want to look into is MySQL's native encryption and decryption functions, which could be used to implement column-level encryption if you're concerned about performance.

昔梦 2024-09-17 17:17:09

虽然最好的解决方案是其他答案建议的抽象层,但您可以使用您自己的版本覆盖现有的 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 一起使用!

对于打字不稳定表示歉意。当我写这个建议时,我的妻子已经对我们的路由器进行了几次弹跳

While the best solution would be the abstraction layer that the other answers have suggested, you can override existing PHP functions with your own versions with the PECL Runkit extension

Something like:

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);
}

Note: By default, only userspace
functions may be removed, renamed, or
modified. In order to override
internal functions, you must enable
the runkit.internal_override setting
in php.ini.

It's not a solution I'd really recommend. I had to do something similar some years back in java, where it was far easier to extend jdbc; but while parsing the syntax of SQL queries is hard enough, it gets harder still if your queries are using bind variables. Watch out for escaped strings! Watch out for any use of related function like mysql_db_query, just in case they're used alongside mysql_query within the application!

Apologies for shaky typing. My wife has been bouncing our router a few times while I'be been writing this suggestion

紫竹語嫣☆ 2024-09-17 17:17:09

我认为自动处理此问题的一种方法是查看 MySQL 代理

并通过它实现加密。大约两年前,当它还处于非常早期的阶段时,我就玩过它,据我记得它基本上可以拦截请求并用它们做“东西”:) 本质上不需要更改代码。
希望这有帮助。

I think one way of handling this automatically would be to look into MySQL proxy

and implement encryption through that. I played around with it 2 or so years ago when it was in a very early stages, and from what I remember it could basically intercept requests and do 'stuff' with them :) No code change required essentially.
Hopefully this helps.

回眸一遍 2024-09-17 17:17:09

有一些商业解决方案可以帮助静态数据加密。您可以查看 Gazzang 或 Packet General。两者都提供 MySQL 加密以帮助满足 HIPPA 合规性。祝你好运

There are commercially available solutions to help with data at rest encryption. You can check out either Gazzang or Packet General. Both offer MySQL encryption to help with HIPPA compliance. Good Luck

美人如玉 2024-09-17 17:17:09

您可以在文件系统级别进行加密,然后让操作系统处理它。如果您希望在 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();
}

You could encrypt at the file system level, and let the OS handle it. If you wish to handle it at the PHP level, extend, don't overwrite.

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();
}
墨小沫ゞ 2024-09-17 17:17:09

我真的认为你从错误的角度看待这个问题。这不是开发人员通过在数据库中存储和检索数据时加密/解密数据来解决的问题 - 使用基础设施解决方案。

考虑硬件或软件全盘加密、通过 RDBMS 的透明数据加密功能(如果特定 RDBMS 有)或通过操作系统对数据库本身进行加密。

请参阅NIST 的此文档

I really think you are looking at this from the wrong perspective. This is not a problem to be solved by developers via encrypting/decrypting data as you store and retrieve it from the database - use an infrastructure solution.

Consider hardware or software whole disk encryption, encryption of the database itself via the RDBMS's transparent data encryption function (if the particular RDBMS has one), or via the OS.

See this document from NIST

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文