Шифрование SQL Server 2005, asp.net и хранимые процедуры - PullRequest
6 голосов
/ 13 сентября 2008

Мне нужно написать веб-приложение с использованием SQL Server 2005, asp.net и ado.net. Большая часть пользовательских данных, хранящихся в этом приложении, должна быть зашифрована (см. HIPAA).

В прошлом для проектов, которые требовали шифрования, я шифровал / расшифровывал в коде приложения. Тем не менее, это было обычно для шифрования паролей или информации о кредитной карте, так что только несколько столбцов в паре таблиц. Для этого приложения гораздо больше столбцов в нескольких таблицах необходимо зашифровать, поэтому я подозреваю, что передача ответственности за шифрование на уровень данных будет более эффективной, особенно с учетом встроенной поддержки SQL Server 2005 для нескольких типов шифрования. (Я мог бы быть убежден иначе, если у кого-то есть реальные, эмпирические доказательства.)

Я проконсультировался с BOL, и я довольно искусен в использовании Google. Поэтому мне не нужны ссылки на онлайн-статьи или документацию MSDN (вероятно, я уже читал их).

Один из подходов, который я обернул до сих пор, - это использование симметричного ключа, который открывается с помощью сертификата.

Итак, однократные этапы настройки (теоретически выполняются администратором базы данных):

  1. Создать мастер-ключ
  2. Резервное копирование Мастер Ключа в файл, запись на CD и сохранение вне сайта.
  3. Откройте мастер-ключ и создайте сертификат.
  4. Резервное копирование сертификата в файл, запись на компакт-диск и сохранение вне сайта.
  5. Создание симметричного ключа с выбранным алгоритмом шифрования с использованием сертификата.

Тогда каждый раз, когда хранимой процедуре (или пользователю-пользователю через Management Studio) требуется доступ к зашифрованным данным, вы должны сначала открыть симметричный ключ, выполнить любые операторы или пакеты tsql, а затем закрыть симметричный ключ.

Тогда, что касается приложения asp.net, а в моем случае уровня доступа к коду приложения, шифрование данных полностью прозрачно.

Итак, мои вопросы:

  1. Хочу ли я открыть, выполнить операторы / пакеты tsql, а затем закрыть симметричный ключ внутри sproc? Опасность, которую я вижу, состоит в том, что если что-то пойдет не так с выполнением tsql, и выполнение кода sproc никогда не достигнет оператора, закрывающего ключ. Я предполагаю, что это означает, что ключ будет оставаться открытым до тех пор, пока sql не убьет SPID, на котором выполняется sproc.

  2. Должен ли я вместо этого рассмотреть три вызова базы данных для любой конкретной процедуры, которую мне нужно выполнить (только когда необходимо шифрование)? Один вызов базы данных, чтобы открыть ключ, второй вызов, чтобы выполнить sproc, и третий вызов, чтобы закрыть ключ. (Каждый вызов обернут в свой собственный цикл try catch, чтобы максимизировать вероятность того, что открытый ключ в конечном итоге будет закрыт.)

  3. Какие-либо соображения мне нужно для использования транзакций на стороне клиента (т.е. мой код является клиентом, и инициирует транзакцию, выполняет несколько sprocs, а затем фиксирует транзакцию в случае успеха)

Ответы [ 3 ]

3 голосов
/ 13 сентября 2008

1) Изучите использование TRY..CATCH в SQL 2005. К сожалению, нет НАКОНЕЧНИКА, поэтому вам придется обрабатывать как случаи успеха, так и ошибки в отдельности.

2) Нет необходимости, если (1) выполняется очистка.

3) На самом деле нет разницы между клиентскими и серверными транзакциями с SQL Server. Connection.BeginTransaction () более или менее выполняет «BEGIN TRANSACTION» на сервере (и System.Transactions / TransactionScope делает то же самое, пока не будет преобразован в распределенную транзакцию). Что касается проблем, связанных с многократным открытием / закрытием ключа внутри транзакции, я не знаю каких-либо проблем, о которых следует знать.

1 голос
/ 13 сентября 2008

Я большой поклонник варианта 3.

Представьте на минуту, что вы собираетесь настроить транзакционную инфраструктуру, где:

  1. Всякий раз, когда должен был быть сделан вызов хранилищу данных, если существующая транзакция не была запущена, она была создана.
  2. Если транзакция уже выполнена, то вызовы подключаются к хранилищу данных в эту транзакцию. Это часто полезно для бизнес-правил, которые вызываются событиями сохранения / перехода в базу данных. IE. Если у вас было правило, что всякий раз, когда вы продали виджет, вам нужно было обновить таблицу WidgetAudit, вы, вероятно, захотите заключить вызов вставки аудита виджета в ту же транзакцию, что и то, что сообщает хранилищу данных, что виджет продан.
  3. Всякий раз, когда исходный вызывающий объект для хранилища данных (из шага 1) завершается, он фиксирует / откатывает транзакцию, которая влияет на все действия базы данных, которые произошли во время ее вызова (с использованием try / catch / finally).

Как только этот тип транзакции создан, становится просто прикрепить открытый ключ в начале (когда транзакция открывается) и закрыть ключ в конце (непосредственно перед завершением транзакции). Выполнение «вызовов» в хранилище данных не так дорого, как открытие соединения с базой данных. Это действительно такие вещи, как SQLConnection.Open (), который сжигает ресурсы (даже если ADO.NET объединяет их для вас).

Если вам нужен пример этих типов кодов, я бы рассмотрел NetTiers. Это довольно элегантное решение для транзакций, которое мы только что описали (при условии, что вы еще ничего не имеете в виду).

Всего 2 цента. Удачи.

0 голосов
/ 13 сентября 2008
  1. вы можете использовать @@ error, чтобы увидеть, не возникло ли ошибок во время вызова sproc в SQL.

  2. Нет сложным.

  3. Вы можете, но я предпочитаю использовать транзакции в самом SQL Server.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...