2010-07-15 14 views
9
información

Antecedentes:

Soy parte de un equipo de desarrolladores que se ejecuta una aplicación web que almacena y recupera datos de HIPAA (médicos). Recientemente, las pautas de HIPAA se actualizaron para incluir una política que requiere que toda la información de identificación del cliente se encripte cuando está "en reposo" (almacenada en la base de datos y no se está accediendo).La sobrecarga de una función nativa de PHP para cifrar los datos de HIPAA

El problema inicial

El primer problema que tuvimos que hacer frente fue la determinación de la mejor manera bidireccional cifrar los datos de una manera que hace que los datos seguros en caso de incumplimiento.

la solución inicial

La solución más rápida que se nos ocurrió fue usar mcrypt para cifrar los datos antes de que lo insertó en la base de datos.

El nuevo problema

La aplicación que estamos desarrollando es bastante antiguo (como aplicaciones web van) y utiliza una gran cantidad de programación de procedimiento, así como la fuerte dependencia de la función mysql_query para insertar, actualizar, recuperar y borrar datos. No tenemos el tiempo ni el lujo de traducir nuestro código a una capa de abstracción de base de datos. Por lo tanto, la única forma de implementar este sistema de cifrado/descifrado es editar manualmente todas las consultas CRUD para usar datos cifrados a través del mcrypt. Esto es muy ineficiente y extremadamente propenso a errores.

Nuestra solución

propuesto Decidimos que la manera más rápida y más eficaz para resolver nuestro problema es sobrescribir la función nativa mysql_query con uno de nuestra propia invención. En nuestra nueva función, cifraríamos/descifraríamos los valores de los datos antes de enviar la consulta al servidor/devolver el conjunto de resultados.

Cuando usted gente vienen en

  1. ¿Es esta la mejor solución para resolver nuestro problema inicial?
  2. ¿Cómo se puede sobreescribir una función PHP central existente?
+0

Así que el problema es para cifrar los datos, mientras que ha sido transferido al servidor de base de datos? ¿O almacenarlo de manera encriptada? –

+0

Para almacenarlo de forma encriptada y luego recuperarlo, descifrarlo y mostrarlo fácilmente según sea necesario. –

+0

Creo que puede estar haciendo esto en la capa incorrecta. ¿Consideró encriptar toda la base de datos MySQL? Algunas soluciones para esto se discuten en [esta pregunta] (http://stackoverflow.com/questions/143750/mysql-and-data-file-encryption). –

Respuesta

3

Aunque haya indicado anteriormente que no puede/no traducirá su código en una capa de abstracción de base de datos, creo que sería la solución ideal. Claro, es mucho más trabajo en este momento, pero vale la pena. Lo que ha propuesto es un truco, que puede (y probablemente lo hará) generar errores y dolores de cabeza en el futuro.

Lo mejor sería cifrar toda la base de datos, tal como se propone en los comentarios. Hay soluciones que hay para el cifrado transparente en diferentes niveles, es decir: this o this

Otra cosa que puede que desee ver en es nativo encryption and decryption funciones de MySQL, que podrían ser utilizados para implementar el cifrado de niveles de columna si está preocupado sobre el rendimiento.

+0

@Aircule Bueno, ese tipo de solución resuelve un problema: cifrar los datos cuando entran en la base de datos. Podríamos usar activadores para encriptar los datos antes de insertarlos o actualizarlos. Sin embargo, ¿qué pasa con la recuperación de datos? –

+0

@Levi ¿No puedes descifrarlo al recuperarlo? – quantumSoup

+0

@ Aircule, sí, podríamos, pero tendríamos que llamar a nuestra función de descifrado de forma manual antes de imprimir los datos para cada consulta y hay miles de consultas codificadas. –

0

Puede cifrar en el nivel del sistema de archivos y dejar que el SO lo maneje. Si desea manejarlo en el nivel de PHP, amplíe, no sobrescriba.

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

Mientras que la mejor solución sería la capa de abstracción que las otras respuestas han sugerido, puede reemplazar las funciones de PHP existente con sus propias versiones con el Algo PECL Runkit extension

como:

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

Nota: De forma predeterminada, solo las funciones de espacio de usuario se pueden eliminar, renombrar o modificar. Para anular las funciones internas , debe habilitar la configuración runkit.internal_override en php.ini.

No es una solución que realmente recomendaría. Tuve que hacer algo similar hace algunos años en Java, donde era mucho más fácil extender jdbc; pero al analizar la sintaxis de las consultas SQL es bastante difícil, se vuelve aún más difícil si sus consultas están utilizando variables de vinculación. ¡Cuidado con las cadenas escapadas! Tenga cuidado con el uso de funciones relacionadas como mysql_db_query, ¡en caso de que se utilicen junto con mysql_query dentro de la aplicación!

Disculpas por tipeo inestable. Mi esposa ha estado rebotando nuestro router unas cuantas veces mientras I'be estado escribiendo esta sugerencia

+0

¿Qué tiene que ver tu enrutador con tu teclado? – blockhead

+0

Cada vez que lo hace, me da nervios –

1

Creo que una manera de manejar esto de forma automática sería mirar en MySQL proxy

e implementar el cifrado a través de eso. Jugué con eso hace unos dos años cuando estaba en una etapa muy temprana, y por lo que recuerdo, básicamente podía interceptar las solicitudes y hacer 'cosas' con ellas :) No es necesario cambiar el código esencialmente. Espero que esto ayude.

1

Existen soluciones disponibles comercialmente para ayudar con el cifrado de datos en reposo. Puede consultar Gazzang o Packet General. Ambos ofrecen cifrado MySQL para ayudar con el cumplimiento de HIPPA. Buena suerte

0

Realmente creo que estás viendo esto desde la perspectiva equivocada. Este no es un problema para ser resuelto por los desarrolladores mediante el cifrado/descifrado de datos a medida que los almacena y los recupera de la base de datos: use una solución de infraestructura.

Considere el cifrado de todo un disco de hardware o software, el cifrado de la base de datos a través de la función de encriptación de datos transparente del RDBMS (si el RDBMS particular tiene uno) o mediante el sistema operativo.

Ver this document from NIST

Cuestiones relacionadas