Domanda

Devo scrivere un'applicazione Web utilizzando SQL Server 2005, asp.net e ado.net.Gran parte dei dati utente archiviati in questa applicazione devono essere crittografati (leggi HIPAA).

In passato, per progetti che richiedevano la crittografia, crittografavo/decifravo il codice dell'applicazione.Tuttavia, in genere si trattava di crittografare password o informazioni sulla carta di credito, quindi solo una manciata di colonne in un paio di tabelle.Per questa applicazione, è necessario crittografare molte più colonne in diverse tabelle, quindi sospetto che trasferire le responsabilità di crittografia al livello dati avrà prestazioni migliori, soprattutto dato il supporto nativo di SQL Server 2005 per diversi tipi di crittografia.(Potrei essere convinto del contrario se qualcuno avesse prove reali ed empiriche.)

Ho consultato BOL e sono abbastanza esperto nell'uso di Google.Quindi non voglio collegamenti ad articoli in linea o documentazione MSDN (è probabile che l'abbia già letto).

Un approccio su cui ho riflettuto finora è quello di utilizzare una chiave simmetrica che viene aperta utilizzando un certificato.

Quindi i passaggi di configurazione una tantum sono (eseguiti in teoria da un DBA):

  1. Crea una chiave principale
  2. Esegui il backup della chiave principale su un file, masterizzala su CD e archiviala fuori sede.
  3. Apri la chiave principale e crea un certificato.
  4. Eseguire il backup del certificato su un file, masterizzarlo su CD e archiviarlo fuori sede.
  5. Crea la chiave simmetrica con l'algoritmo di crittografia preferito utilizzando il certificato.

Quindi, ogni volta che una procedura memorizzata (o un utente umano tramite Management Studio) deve accedere ai dati crittografati, è necessario prima aprire la chiave simmetrica, eseguire eventuali istruzioni o batch tsql e quindi chiudere la chiave simmetrica.

Quindi, per quanto riguarda l'applicazione asp.net, e nel mio caso il livello di accesso ai dati del codice dell'applicazione, la crittografia dei dati è completamente trasparente.

Quindi le mie domande sono:

  1. Voglio aprire, eseguire istruzioni/batch tsql e quindi chiudere la chiave simmetrica all'interno di sproc?Il pericolo che vedo è: cosa succede se qualcosa va storto con l'esecuzione di tsql e l'esecuzione del codice sproc non raggiunge mai l'istruzione che chiude la chiave.Presumo che ciò significhi che la chiave rimarrà aperta finché sql non ucciderà lo SPID su cui è stato eseguito sproc.

  2. Dovrei invece considerare di effettuare tre chiamate al database per ogni determinata procedura che devo eseguire (solo quando è necessaria la crittografia)?Una chiamata al database per aprire la chiave, una seconda chiamata per eseguire sproc e una terza chiamata per chiudere la chiave.(Ogni chiamata è racchiusa nel proprio try catch loop per massimizzare le probabilità che una chiave aperta alla fine venga chiusa.)

  3. Qualche considerazione di cui dovrei aver bisogno per utilizzare le transazioni lato client (il che significa che il mio codice è il client e avvia una transazione, esegue diversi sproc e quindi esegue il commit della transazione presupponendo che abbia successo)?

È stato utile?

Soluzione

1) Cerca di utilizzare TRY..CATCH in SQL 2005.Sfortunatamente non esiste FINALMENTE, quindi dovrai gestire individualmente sia i casi di successo che quelli di errore.

2) Non necessario se (1) gestisce la pulizia.

3) Non c'è realmente una differenza tra le transazioni client e server con SQL Server.Connection.BeginTransaction() esegue più o meno "BEGIN TRANSACTION" sul server (e System.Transactions/TransactionScope fa lo stesso, finché non viene promosso a transazione distribuita).Per quanto riguarda le preoccupazioni relative all'apertura/chiusura della chiave più volte all'interno di una transazione, non conosco alcun problema di cui essere a conoscenza.

Altri suggerimenti

Sono un grande fan dell'opzione 3.

Fai finta per un minuto di voler configurare comunque un'infrastruttura di transazione dove:

  1. Ogni volta che stava per essere effettuata una chiamata al datastore se una transazione esistente non era stata avviata, ne veniva creata una.
  2. Se una transazione è già in atto, le chiamate all'archivio dati si collegano a quella transazione.Ciò è spesso utile per le regole aziendali generate da eventi di salvataggio/accesso al database.CIOÈ.Se avessi una regola secondo cui ogni volta che vendi un widget devi aggiornare una tabella WidgetAudit, probabilmente vorresti racchiudere la chiamata di inserimento dell'audit del widget nella stessa transazione in cui indica al datastore che un widget è stato venduto.
  3. Ogni volta che il chiamante originale dell'archivio dati (dal passaggio 1) termina, esegue il commit/il rollback della transazione, che influisce su tutte le azioni del database che si sono verificate durante la sua chiamata (utilizzando un try/catch/finally).

Una volta creato questo tipo di transazione, diventa semplice aggiungere una chiave aperta all'inizio (quando la transazione si apre) e chiudere la chiave alla fine (appena prima della fine della transazione).Effettuare "chiamate" al datastore non è così costoso come aprire una connessione al database.Sono davvero cose come SQLConnection.Open() che bruciano risorse (anche se ADO.NET le raggruppa per te).

Se vuoi un esempio di questi tipi di codici, prenderei in considerazione la possibilità di guardare NetTiers.Ha una soluzione piuttosto elegante per le transazioni che abbiamo appena descritto (supponendo che tu non abbia già qualcosa in mente).

Solo 2 centesimi.Buona fortuna.

  1. puoi usare @@error per vedere se si sono verificati errori durante la chiamata a sproc in SQL.

  2. No al complicato.

  3. Puoi, ma preferisco utilizzare le transazioni nello stesso SQL Server.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top