解密 SQL Server 对象
解密 SQL Server 中的存储过程、视图、函数和触发器
引言
有一种快速简便的方法可以解密 SQL Server 中的对象,这是执行此任务的另一种编程方法。 Optillect SQL Decryptor 工具是一个免费工具,可用于此目的,并允许从同一数据库中解密函数、触发器和视图。
背景
在处理旧版数据库时,有时开发人员可能会遇到无法查看或修改的加密对象。当调试或逆向工程 SQL Server 对象时,这可能会成为一个问题。本文的目的是演示使用 Optillect SQL Decryptor 工具处理 SQL Server 中加密对象的快速方法。
该工具支持以下版本
- SQL Server 2000
- SQL Server 2005
- SQL Server 2008
- SQL Server 2008 R2
- SQL Server 2011
流程
演示此过程的方法是创建一个架构,然后创建一个调用加密视图的加密存储过程。将使用 Optillect 解密这两个对象,然后在 SSMS 中修改它们,并将更改应用到数据库。
创建数据库架构
用于创建此架构以及本文中使用到的相关 SQL Server 对象的脚本可以从这个 zip 文件下载。
表关系如下
- 一个 `User` 可以属于多个 `Group`
- 一个 `Group` 可以拥有多个 `User`
- 一个 `Group` 可以拥有多个 `Permission`
- 一个 `Permission` 可以与多个 `Group` 相关联
简而言之,`User` 和 `Group` 之间存在多对多关系,这里使用名为 `UserGroup` 的链接表来实现。同样,`GroupPermisison` 表用于建立 `Group` 和 `Permission` 表之间的多对多关系。
创建加密对象
创建上述数据库后,还需要创建以下加密的 SQL Server 对象。
视图
此视图返回 `User` 表中的所有活动用户,以及他们所属的组以及与组关联的每个 `permission`。
create view vwUserGroupPermissions
with encryption as
select
u.ID as 'UserID',
u.Firstname,
u.Surname,
u.Email,
u.Active,
u.DateCreated,
g.Name as 'Group',
g.ID as 'GroupID',
p.Name as 'Permission',
p.ID as 'PermssionID'
from [user] u
inner join usergroup ug on u.id = ug.UserID
inner join [group] g on g.ID = ug.GroupID
inner join GroupPermission gp on gp.GroupID = g.ID
inner join [Permisson] p on p.ID = gp.PermissionID
where u.Active = 1
存储过程
下面的存储过程调用 `vwUserGroupPermissions` 视图,并根据 `DateCreated` 列过滤返回的数据,即返回 `DateCreateStart` 和 `DateCreatedEnd` 日期范围内内的所有行。
create procedure spGetActiveUsersByDateCreated
@DateCreatedStart datetime = null,
@DateCreatedEnd datetime = null
with encryption as
select * from vwUserGroupPermissions v
where
(v.DateCreated BETWEEN @DateCreatedStart AND @DateCreatedEnd)
数据库
创建数据库和这两个对象后,SSMS 中的服务器资源管理器窗口应显示如下
两个对象都显示一个锁图标,表示它们已加密。当开发人员选择 **脚本存储过程为 -> 修改为 -> 新查询编辑器窗口** 时,由于加密,将显示以下预期错误
Property TextHeader is not available for StoredProcedure '[dbo].[spGetActiveUsersByDateCreated]'. This property may not exist for this object, or may not be retrievable due to insufficient access rights. The text is encrypted. (Microsoft.SqlServer.Smo)
解密 SQL Server 对象
单击此 站点上的 **直接下载链接** 来安装并运行 Optillect Decryptor 工具。
安装完成后,创建一个专用的管理员连接(DAC)以访问 SQL Server 数据库引擎的运行实例,如下所示
登录时,确保输入了 **admin: server\instance name**。如果登录成功,`Users` 数据库将显示如下
上图显示已建立到 SQL Sever 的 DAC 连接。现在,我们将分别展开 `Users` 数据库,然后展开 Procedures 和 Views 节点,如下所示。
右键单击 `vwUserGroupPermission` 并从菜单中选择 **显示 DDL 脚本** 选项。以下解密后的 T-SQL 显示在右侧窗格中。
再次,对 `spGetActiveUsersByDateCreated` 执行相同的操作,以查看解密后的 T-SQL,如下所示。
Optillect 的一个限制是无法修改 T-SQL 并应用更改,但可以从“文件”菜单选项中将脚本保存到文件,并在 SSMS 中打开以进行更改。
选择 **文件 -> 将 DLL 脚本保存到文件**,然后单击“保存”按钮。
单击显示 `spGetActiveUsersByDateCreated` 的 T-SQL 的选项卡,并以相同的方式保存脚本。
在 **应用更改** 部分,我们将研究如何修改已保存的脚本并使用 SSMS 应用这些更改。
移除加密
右键单击 `spGetActiveUserByDateRange` 存储过程,然后选择 **原地解密** 菜单选项。现在右键单击存储过程并选择 **显示 DDL 脚本**。
数据库中的 `with encryption` 子句已被删除。
处理多个 SQL Server 对象
还可以解密数据库中的多个对象,并将脚本保存到一个文件中,或者为每个对象保存到一个单独的文件。如果我们希望获取一个加密的数据库并将所有对象保存到脚本文件或一组脚本文件中,这是一个方便的选项。然后可以使用这些脚本来创建另一个数据库,例如用于开发、测试或 UAT 环境。
右键单击 `Users` 数据库并选择 **解密向导**。
向导默认列出了数据库中的所有对象,包括存储过程、视图、函数、触发器,以及数据库和表级别。为了限制列表到特定类型的对象,可以使用右侧的按钮来打开和关闭过滤器。
**输出类型** 下拉列表允许将所有选定对象的 T-SQL 保存到一个文件或单独的文件中。从同一个下拉列表中选择 **原地解密** 选项,使用户能够删除所有选定对象上的加密,并直接将此更改应用到数据库。
应用脚本更改
在 SSMS 中打开之前解密的两个文件。
修改 `spGetActiveUsersByDateCreated` 存储过程,如下所示。
alter procedure spGetActiveUsersByDateCreated @DateCreatedStart datetime = null, @DateCreatedEnd datetime = null with encryption as select * from vwUserGroupPermissions v where (v.DateCreated BETWEEN @DateCreatedStart AND @DateCreatedEnd) order by v.DateCreated desc
上述更改应用了一个 `order by` 子句,以按创建日期降序列表用户。 `Create` 子句也已更改为 `Alter` 子句。
修改 `vwUserGroupPermissions` 视图,如下所示。
alter view vwUserGroupPermissions
with encryption as
select
u.ID as 'UserID',
u.Firstname,
u.Surname,
-- u.Email,
u.Active,
u.DateCreated,
g.Name as 'Group',
g.ID as 'GroupID',
p.Name as 'Permission',
p.ID as 'PermssionID'
from [user] u
inner join usergroup ug on u.id = ug.UserID
inner join [group] g on g.ID = ug.GroupID
inner join GroupPermission gp on gp.GroupID = g.ID
inner join [Permisson] p on p.ID = gp.PermissionID
where u.Active = 1
视图已更改为删除 `email` 列。同样,`Create` 子句也已更改为 `Alter` 子句。
现在在 SSMS 中运行这两个脚本以将更改应用到 `Users` 数据库。
测试脚本更改
为了测试更改是否已应用,请在 SSMS 中运行以下语句。
declare @startdate datetime = '2014.01.01'
declare @enddate datetime = convert( varchar(20), getdate(), 102 )
exec spGetActiveUsersByDateCreated @DateCreatedStart = @startdate ,@DateCreatedEnd = @enddate
已删除 `email` 列,并且结果按 `DateCreated` 列的降序排序。
最后确认,在 Optillect 中打开这两个对象,并检查 DLL 以查看更改是否在修改后的 T-SQL 中可见。
关注点
- 如果 DAC 连接失败,可能需要关闭所有到数据库的开放连接,然后重试。
- 展开过程节点时,如果存储过程很多,可能需要一段时间才能列出所有存储过程。向导也一样,在某些情况下 Optillect 会显示超时错误。
- 无法在 SSMS 中打开 DAC 连接。
- 虽然可以在 Optillect 中从选定对象中移除加密,但无法修改 T-SQL。
结论
本文介绍了一种使用名为 Optillect SQL Decryptor 的免费第三方工具来快速简便地解密 SQL Server 对象的方法,而无需编写复杂的解密算法。这使得开发人员可以将节省的时间用于关注脚本内容。
在维护和调试旧代码时,有时会发现错误源于特定的存储过程。尝试在 SSMS 中打开此存储过程会因对象已加密而导致错误。Optillect SQL Decryptor 是克服此障碍的快速方法,并提供了对问题存储过程 DDL 脚本的有用了解。如果这是一个难以调试的复杂例程,可以暂时在数据库中移除该对象的加密。这样就可以在 Visual Studio 中打开存储过程,通过设置断点并逐行执行 T-SQL 来调试,以更好地理解例程并查明错误原因。
该工具还可以方便地移除数据库中所有对象的加密,而无需创建新数据库。另一方面,可以保留现有的生产数据库,并将对象的 DDL 脚本导出到脚本文件。可以从此脚本文件为开发环境创建一个新数据库,使开发团队能够应用修改,例如添加错误处理、删除冗余表、修改视图以适应已删除的对象、事务处理以及一般的错误修复,例如解决 `null` 错误。完成修改后,可以将数据库移植到测试环境,然后移至 UAT 环境。如果测试团队获得绿色通行证,则可以用带有增强功能的新数据库替换原始生产数据库。
修订历史
版本 1.0
- 创建的第一个版本