6

我需要使用 SQL Server 2005、asp.net 和 ado.net 编写一个 Web 应用程序。此应用程序中存储的大部分用户数据都必须加密(读取 HIPAA)。

过去对于需要加密的项目,我在应用程序代码中加密/解密。但是,这通常用于加密密码或信用卡信息,因此在几个表中只有少数列。对于这个应用程序,多个表中的更多列需要加密,因此我怀疑将加密职责推入数据层会更好,特别是考虑到 SQL Server 2005 对多种加密类型的本机支持。(如果有人有真实的经验证据,我可能会被说服。)

我咨询过 BOL,我相当擅长使用 google。所以我不想要在线文章或 MSDN 文档的链接(我可能已经阅读过它)。

到目前为止,我已经想到的一种方法是使用使用证书打开的对称密钥。

所以一次性设置步骤是(理论上由 DBA 执行):

  1. 创建主密钥
  2. 将主密钥备份到文件,刻录到 CD 并在异地存储。
  3. 打开主密钥并创建证书。
  4. 将证书备份到文件,刻录到 CD 并异地存储。
  5. 使用证书创建具有所选加密算法的对称密钥。

然后,每当存储过程(或通过 Management Studio 的人类用户)需要访问加密数据时,您必须首先打开对称密钥,执行任何 tsql 语句或批处理,然后关闭对称密钥。

然后就 asp.net 应用程序而言,在我的例子中是应用程序代码的数据访问层,数据加密是完全透明的。

所以我的问题是:

  1. 我是否要打开、执行 tsql 语句/批处理,然后关闭存储过程中的所有对称密钥?我看到的危险是,如果 tsql 执行出现问题怎么办,并且代码 sproc 执行永远不会到达关闭密钥的语句。我假设这意味着密钥将保持打开状态,直到 sql 杀死 sproc 执行的 SPID。

  2. 我是否应该考虑对我需要执行的任何给定过程进行三个数据库调用(仅在需要加密时)?一次数据库调用打开密钥,第二次调用执行存储过程,第三次调用关闭密钥。(每个调用都包含在自己的 try catch 循环中,以最大化打开密钥最终关闭的几率。)

  3. 我需要使用客户端事务(意味着我的代码是客户端,并启动事务,执行几个 sproc,然后假设成功提交事务)有什么注意事项吗?

4

3 回答 3

3

1) 考虑在 SQL 2005 中使用 TRY..CATCH。不幸的是,没有 FINALLY,因此您必须分别处理成功和错误情况。

2) 如果 (1) 处理清理,则不需要。

3) SQL Server 的客户端和服务器事务之间没有真正的区别。Connection.BeginTransaction() 或多或少在服务器上执行“BEGIN TRANSACTION”(System.Transactions/TransactionScope 也是如此,直到它被提升为分布式事务)。至于在事务中多次打开/关闭密钥的问题,我不知道有什么需要注意的问题。

于 2008-09-12T22:41:47.177 回答
1

我是选项 3 的忠实粉丝。

假装你要在任何地方建立交易基础设施:

  1. 如果现有事务尚未启动,则每当要调用数据存储时,就会创建一个。
  2. 如果事务已经到位,则调用数据存储挂钩到该事务。这对于保存/进入数据库事件引发的业务规则通常很有用。IE。如果您有一条规则,即每当您出售一个小部件时,您需要更新一个 WidgetAudit 表,您可能希望将小部件审计插入调用包装在与告诉数据存储小部件已售出的事务相同的事务中。
  3. 每当数据存储的原始调用者(来自步骤 1)完成时,它都会提交/回滚事务,这会影响在其调用期间发生的所有数据库操作(使用 try/catch/finally)。

一旦创建了这种类型的交易,那么在开始时(当交易打开时)添加打开的密钥并在结束时(就在交易结束之前)关闭密钥变得很简单。对数据存储进行“调用”并不像打开与数据库的连接一样昂贵。确实是像 SQLConnection.Open() 这样的东西会消耗资源(即使 ADO.NET 正在为您汇集它们)。

如果您想要这些类型代码的示例,我会考虑查看 NetTiers。它为我们刚刚描述的事务提供了一个非常优雅的解决方案(假设您还没有想到什么)。

只需2美分。祝你好运。

于 2008-09-13T07:04:49.230 回答
0
  1. 您可以使用@@error 查看在调用 SQL 中的存储过程期间是否发生任何错误。

  2. 不复杂。

  3. 你可以,但我更喜欢在 SQL Server 本身中使用事务。

于 2008-09-12T22:10:42.900 回答