65.9K
CodeProject 正在变化。 阅读更多。
Home

SQL Server存储过程和函数加密

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.80/5 (6投票s)

2009年2月12日

CPOL

4分钟阅读

viewsIcon

30641

downloadIcon

1130

此应用程序回答了“如何一次性加密SQL Server存储过程和函数”的问题

SqlProcedureEncryption2.jpg

引言

让我们来讨论 SQL Server 中的“With Encryption”语句。当我们发布一个基于 SQL 数据库的应用程序时,我们必须将数据库文件附加到项目中。我的意思是,我们必须将 MDF 文件,有时还有 LDF 文件包含在项目中。然而,我们知道,有了这些文件,任何人都可以用 Management Studio 附加它们并查看我们的数据库对象。

幸运的是,有一些方法可以隐藏我们的数据库结构不被最终用户看到。例如,我们可以用数字这样的特殊格式命名表和列,这样用户就无法猜测它们的含义,并将单元格的内容保存为二进制格式,但实际上所有这些方法都会降低性能。

可以说,SQL Server 2008 中的加密已经从根本上解决了。您可以在 Microsoft 搜索这篇文章以获取有关加密的更多信息:“SQL Server 2008 企业版数据库加密”。

好的。所以我们可以使用“With Encryption”语句来加密存储过程和函数,以及视图。存储过程和函数可以被加密,以便没有人可以看到它们的源代码。您只需要使用“With Encryption”选项来创建或修改函数。当您使用 With Encryption 创建存储过程时,存储过程的代码将被加密然后保存在数据库中。

SQL Server 将能够使用源代码的加密版本在需要时重新编译存储过程,但任何用户都无法获取它。实际上,您不应该依赖 SQL Server 加密来保护您的代码。

在互联网上可以找到破解 SQL Server 加密的方法,但有时我们不得不使用加密,因为在一些国家没有版权保护。请记住,如果您使用 With Encryption 创建存储过程,您将无法修改它。您必须另行备份。

背景

假设在我们的公司有一个项目,涉及到 500 多个存储过程和函数。每次我们要发布一个版本时,我们都必须手动加密所有存储过程和函数。SQL Server 没有提供任何过程或工具来一次一个地加密它们,或者至少我不知道。

我搜索了这个问题,幸运的是我找到了“Chris Morton”的一篇文章,这真的帮助了我,但尽管如此,仍然存在一些问题。

它的一些问题;

  1. 它直接从 sys.syscomments 获取存储过程的源代码。除非存储过程被加密,否则存储过程的源代码将被记录在 sys.syscomments 系统表中。源代码存储在一个名为 'text' 的字段中。

    该字段的数据类型是 nvarchar(4000)。幸运的是,这并不意味着存储过程限于 4,000 个字符。如果存储过程超过 4,000 个字符,SQL Server 会分配额外的记录,并递增 'colid' 字段。

    所以当存储过程的源代码超过 4000 时,对于包含过程下一部分的下一条记录就会发生错误。为了解决这个问题,我使用了 SQL Server 函数 object_definition(object_id),它返回过程的完整源代码。

  2. 我曾说过,所有过程都保存在 sys.syscomments 中,除了加密的过程,但它没有将这个条件包含在返回过程列表的主要 select 查询中,所以在执行之后,下次执行时就会出现错误。

    //
    // SELECT [name], object_definition(object_id) as [text] from sys.objects where [
    //      type]='P' and object_definition(object_id) is not null 
    //
  3. 它的加密过程和函数的策略如下:

    对于 sys.syscomments 中的每个过程,首先要获取过程的头部部分,获取过程的头部部分

    它从 Create Proc 语句解析到过程的 Begin 语句,并在获取头部部分最后一个 As 语句的索引后,用 As 语句替换 with encryption + char(13) + As,然后再次修改最终过程。

    但我们知道有些过程不包含 Begin End 语句,那么我们该怎么办?

    为了解决这个问题,我基于 As 语句执行操作,因为每个过程、函数或视图都必须以 As 语句开头。

Using the Code

SqlProcedureEncryption1.jpg

我已经包含了源代码。我包含了三个 SQL 脚本文件,其中包含了我用于加密的函数和过程。您可以直接使用它们进行加密,而无需运行应用程序。但我开发了一个小的 VB.NET 应用程序,以便更轻松地完成。

因为加密后无法使用过程的源代码,所以应用程序会将它们备份到您用应用程序指定的表名中。

//
// SELECT [name], object_definition(object_id) as [text] from sys.objects where [type]=
//     'P' and object_definition(object_id) is not null 
//
© . All rights reserved.