2010-07-15 17 views
9
Informazioni

Background:

faccio parte di un team di sviluppatori che esegue un'applicazione web che memorizza e recupera i dati HIPAA (medici). Recentemente, le linee guida HIPAA sono state aggiornate per includere un criterio che richiede che tutte le informazioni identificative dei client vengano crittografate quando sono "a riposo" (memorizzate nel database e non accessibili).Il sovraccarico di una funzione PHP nativa per crittografare i dati per la conformità HIPAA

il problema iniziale

Il primo problema che abbiamo dovuto affrontare è stato determinare il modo migliore per bidirezionale crittografare i dati in un modo che rende i dati sicuri in caso di violazione.

soluzione iniziale

La soluzione più veloce siamo arrivati ​​a era quello di utilizzare mcrypt per crittografare i dati prima di abbiamo inserito nel database.

il nuovo problema

L'applicazione che stiamo sviluppando è piuttosto vecchio (come le applicazioni web Go) e usa un sacco di programmazione procedurale, così come forte dipendenza della funzione mysql_query per inserire, aggiornare, recuperare, e cancella i dati Non abbiamo il tempo o il lusso di tradurre il nostro codice in un livello di astrazione del database. Quindi, l'unico modo per implementare questo sistema di crittografia/decrittografia è quello di modificare manualmente tutte le query CRUD per utilizzare i dati che sono stati crittografati tramite mcrypt. Questo è molto inefficiente ed estremamente soggetto a errori.

La nostra Soluzione proposta

Abbiamo deciso che il modo più veloce ed efficace per risolvere il nostro problema è quello di sovrascrivere la funzione nativa mysql_query con uno dei nostri stessi concepite. Nella nostra nuova funzione, cripteremo/decodificheremo i valori dei dati prima di inviare la query al server/restituire il set di risultati.

Where You gente venire in

  1. È questa la soluzione migliore per risolvere il nostro problema iniziale?
  2. Come si fa a sovrascrivere una funzione PHP di base esistente?
+0

Quindi il problema è di crittografare i dati mentre è stato trasferito al DB server? O memorizzarlo in modo criptato? –

+0

Per memorizzarlo in modo crittografato, quindi recuperarlo, decrittografarlo e visualizzarlo secondo necessità. –

+0

Penso che potresti farlo al livello sbagliato. Hai preso in considerazione la crittografia dell'intero database MySQL? Alcune soluzioni per questo sono discusse in [questa domanda] (http://stackoverflow.com/questions/143750/mysql-and-data-file-encryption). –

risposta

3

Anche se in precedenza hai dichiarato che non puoi/non tradurrò il tuo codice in un livello di astrazione del database, credo che sarebbe la soluzione ideale. Certo, ora c'è molto più lavoro, ma paga. Quello che hai proposto è un hack, che può (e probabilmente lo farà) portare a errori e mal di testa in futuro.

La cosa migliore sarebbe criptare l'intero database, come proposto nei commenti. Ci sono soluzioni là fuori per la crittografia trasparente in diversi livelli, vale a dire: this o this

Un'altra cosa che si potrebbe voler esaminare è nativo encryption and decryption funzioni di MySQL, che potrebbero essere utilizzati per implementare la crittografia a livello di colonna se siete preoccupati sulle prestazioni.

+0

@Aircule Ok, questo tipo di soluzione risolve un problema: crittografare i dati quando vengono inseriti nel DB. Potremmo usare i trigger per crittografare i dati prima di inserirli o aggiornarli. Tuttavia, per quanto riguarda il recupero dei dati? –

+0

@Levi Non puoi decrittografarlo al momento del recupero? – quantumSoup

+0

@Aircule, sì, abbiamo potuto, ma avremmo dovuto chiamare manualmente la funzione di decifratura prima di stampare i dati per ogni query e ci sono migliaia di query hard-coded. –

0

È possibile crittografare a livello di file system e consentire al sistema operativo di gestirlo. Se desideri gestirlo a livello di PHP, estendi, non sovrascrivere.

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

Mentre la soluzione migliore sarebbe il livello di astrazione che le altre risposte hanno suggerito, è possibile escludere funzioni PHP esistente con le proprie versioni con il PECL Runkit extension

Qualcosa di simile:

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: per impostazione predefinita, solo le funzioni userspace possono essere rimosse, rinominate o modificate . Per ignorare le funzioni interne di , è necessario abilitare l'impostazione runkit.internal_override in php.ini.

Non è una soluzione che consiglio davvero. Ho dovuto fare qualcosa di simile qualche anno fa in Java, dove era molto più facile estendere jdbc; ma mentre si analizza la sintassi delle query SQL è abbastanza difficile, diventa ancora più difficile se le query utilizzano variabili di bind. Fai attenzione alle corde scappate! Fai attenzione a qualsiasi funzione correlata come mysql_db_query, nel caso in cui vengano utilizzati insieme a mysql_query all'interno dell'applicazione!

Ci scusiamo per la tipizzazione tremolante. Mia moglie è stata rimbalzando nostro router un paio di volte mentre I'be scritto questo suggerimento

+0

Che cosa ha a che fare il tuo router con la tua tastiera? – blockhead

+0

Ogni volta che lo fa, mi dà il nervosismo –

1

Penso che un modo di gestire automaticamente potrebbe essere quella di guardare in MySQL proxy

e implementare la crittografia attraverso quella. Ci ho giocato circa 2 anni fa quando era in una fase iniziale, e da quello che ricordo potrebbe fondamentalmente intercettare le richieste e fare 'cose' con loro :) Nessun cambiamento di codice richiesto essenzialmente. Speriamo che questo aiuti.

1

Esistono soluzioni disponibili in commercio per facilitare la crittografia dei dati a riposo. Puoi controllare Gazzang o Packet General. Entrambi offrono crittografia MySQL per aiutare con la conformità HIPPA. Good Luck

0

Penso davvero che tu stia guardando questo dalla prospettiva sbagliata. Questo non è un problema da risolvere dagli sviluppatori tramite la crittografia/decrittografia dei dati man mano che li archivi e li recuperi dal database - usa una soluzione di infrastruttura.

Considerare l'hardware o il software di crittografia dell'intero disco, la crittografia del database stesso tramite la funzione di crittografia dei dati trasparente di RDBMS (se il particolare RDBMS ne ha uno) o tramite il sistema operativo.

Vedi this document from NIST

Problemi correlati