Question

Je dois écrire une application Web à l'aide de SQL Server 2005, asp.net et ado.net.Une grande partie des données utilisateur stockées dans cette application doivent être cryptées (lire HIPAA).

Dans le passé, pour les projets nécessitant un cryptage, je chiffrais/déchiffrais le code de l'application.Cependant, il s'agissait généralement de chiffrer des mots de passe ou des informations de carte de crédit, donc seulement une poignée de colonnes dans quelques tables.Pour cette application, beaucoup plus de colonnes dans plusieurs tables doivent être chiffrées. Je pense donc que transférer les responsabilités de chiffrement dans la couche de données sera plus performant, en particulier compte tenu de la prise en charge native par SQL Server 2005 de plusieurs types de chiffrement.(Je pourrais être convaincu du contraire si quelqu'un disposait de preuves réelles et empiriques.)

J'ai consulté BOL et je suis assez doué pour utiliser Google.Je ne veux donc pas de liens vers des articles en ligne ou de la documentation MSDN (il est probable que je l'ai déjà lu).

Une approche que j'ai envisagée jusqu'à présent consiste à utiliser une clé symétrique qui est ouverte à l'aide d'un certificat.

Ainsi, les étapes de configuration uniques sont (effectuées par un administrateur de base de données en théorie) :

  1. Créer une clé principale
  2. Sauvegardez la clé principale dans un fichier, gravez-la sur CD et stockez-la hors site.
  3. Ouvrez la clé principale et créez un certificat.
  4. Sauvegardez le certificat dans un fichier, gravez-le sur CD et stockez-le hors site.
  5. Créez la clé symétrique avec l'algorithme de chiffrement de votre choix à l'aide du certificat.

Ensuite, chaque fois qu'une procédure stockée (ou un utilisateur humain via Management Studio) a besoin d'accéder à des données cryptées, vous devez d'abord ouvrir la clé symétrique, exécuter des instructions ou des lots tsql, puis fermer la clé symétrique.

Ensuite, en ce qui concerne l'application asp.net, et dans mon cas la couche d'accès aux données du code de l'application, le cryptage des données est entièrement transparent.

Mes questions sont donc :

  1. Est-ce que je veux ouvrir, exécuter des instructions/lots tsql, puis fermer la clé symétrique dans le sproc ?Le danger que je vois est le suivant : que se passe-t-il si quelque chose ne va pas avec l'exécution de tsql et que l'exécution du code sproc n'atteint jamais l'instruction qui ferme la clé.Je suppose que cela signifie que la clé restera ouverte jusqu'à ce que SQL tue le SPID sur lequel sproc s'est exécuté.

  2. Dois-je plutôt envisager de faire trois appels à la base de données pour une procédure donnée que je dois exécuter (uniquement lorsque le cryptage est nécessaire) ?Un appel à la base de données pour ouvrir la clé, un deuxième appel pour exécuter la procédure et un troisième appel pour fermer la clé.(Chaque appel est enveloppé dans sa propre boucle try catch afin de maximiser les chances qu'une clé ouverte soit finalement fermée.)

  3. Y a-t-il des considérations à prendre en compte si je dois utiliser des transactions côté client (ce qui signifie que mon code est le client et initie une transaction, exécute plusieurs sprocs, puis valide la transaction en supposant qu'elle réussisse) ?

Était-ce utile?

La solution

1) Envisagez d'utiliser TRY..CATCH dans SQL 2005.Malheureusement, il n'y a pas de FINALLY, vous devrez donc gérer les cas de réussite et d'erreur individuellement.

2) Pas nécessaire si (1) gère le nettoyage.

3) Il n'y a pas vraiment de différence entre les transactions client et serveur avec SQL Server.Connection.BeginTransaction() exécute plus ou moins "BEGIN TRANSACTION" sur le serveur (et System.Transactions/TransactionScope fait de même, jusqu'à ce qu'il soit promu en transaction distribuée).En ce qui concerne les problèmes liés à l'ouverture/fermeture de la clé plusieurs fois au cours d'une transaction, je ne connais aucun problème dont il faut être conscient.

Autres conseils

Je suis un grand fan de l'option 3.

Imaginez un instant que vous alliez de toute façon mettre en place une infrastructure de transaction où :

  1. Chaque fois qu'un appel à la banque de données était sur le point d'être effectué si une transaction existante n'avait pas été démarrée, une était créée.
  2. Si une transaction est déjà en place, les appels au magasin de données s'intègrent à cette transaction.Ceci est souvent utile pour les règles métier déclenchées par des événements de sauvegarde/d'accès à la base de données.C'EST À DIRE.Si vous aviez une règle selon laquelle chaque fois que vous vendiez un widget, vous deviez mettre à jour une table WidgetAudit, vous voudriez probablement envelopper l'appel d'insertion d'audit du widget dans la même transaction que celle qui indique à la banque de données qu'un widget a été vendu.
  3. Chaque fois que l'appelant d'origine de la banque de données (à partir de l'étape 1) a terminé, il valide/annule la transaction, ce qui affecte toutes les actions de base de données qui se sont produites lors de son appel (à l'aide d'un try/catch/finally).

Une fois ce type de transaction créé, il devient simple d'ajouter une clé ouverte au début (lorsque la transaction s'ouvre) et de fermer la clé à la fin (juste avant la fin de la transaction).Passer des « appels » vers la banque de données n'est pas aussi coûteux que d'ouvrir une connexion à la base de données.Ce sont vraiment des choses comme SQLConnection.Open() qui brûlent des ressources (même si ADO.NET les regroupe pour vous).

Si vous voulez un exemple de ces types de codes, j'envisagerais de consulter NetTiers.Il propose une solution assez élégante pour les transactions que nous venons de décrire (en supposant que vous n'ayez pas déjà quelque chose en tête).

Juste 2 centimes.Bonne chance.

  1. vous pouvez utiliser @@error pour voir si des erreurs se sont produites lors de l'appel à une procédure dans SQL.

  2. Non, c'est compliqué.

  3. Vous pouvez mais je préfère utiliser les transactions dans SQL Server lui-même.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top