SQLSERVER对加密的存储过程、视图、触发器进行解密

  • A+
所属分类:数据库技术

这篇文章主要介绍了SQLSERVER对加密的存储过程、视图、触发器进行解密,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

加密测试的存储过程

  1. IF EXISTS(SELECT 1 FROM SYSOBJECTS WHERE TYPE='P' AND NAME='P_TEST')
  2. DROP PROCEDURE P_TEST
  3. GO
  4. CREATE PROCEDURE P_TEST(@USERNAME VARCHAR(20),@MSG VARCHAR(20) OUTPUT)
  5. WITH ENCRYPTION
  6. AS
  7. BEGIN
  8.   IF(SELECT COUNT(1) FROM Custs WHERE NAME=@USERNAME)>0
  9.     SET @MSG='此用户名存在'
  10.   ELSE
  11.     SET @MSG='此用户名不存在'
  12. END

解密的存储过程

  1. Create PROCEDURE Decryption(@procedure sysname = NULL)
  2. AS
  3. SET NOCOUNT ON
  4. DECLARE @intProcSpace bigint, @t bigint, @maxColID smallint,@procNameLength int
  5. select @maxColID = max(subobjid) FROM
  6. sys.sysobjvalues WHERE objid = object_id(@procedure)
  7. --select @maxColID as 'Rows in sys.sysobjvalues'
  8. select @procNameLength = datalength(@procedure) + 29
  9. DECLARE @real_01 nvarchar(max)
  10. DECLARE @fake_01 nvarchar(max)
  11. DECLARE @fake_encrypt_01 nvarchar(max)
  12. DECLARE @real_decrypt_01 nvarchar(max),@real_decrypt_01a nvarchar(max)
  13. declare @objtype varchar(2),@ParentName nvarchar(max)
  14. select @real_decrypt_01a = ''
  15. --提取对象的类型如是存储过程还是函数,如果是触发器,还要得到其父对象的名称
  16. select @objtype=type,@parentname=object_name(parent_object_id)
  17. from sys.objects where [object_id]=object_id(@procedure)
  18. -- 从sys.sysobjvalues里提出加密的imageval记录
  19. SET @real_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid =
  20. object_id(@procedure) and valclass = 1 order by subobjid)
  21. --创建一个临时表
  22. create table #output ( [ident] [int] IDENTITY (11) NOT NULL ,
  23. [real_decrypt] NVARCHAR(MAX) )
  24. --开始一个事务,稍后回滚
  25. BEGIN TRAN
  26. --更改原始的存储过程,用短横线替换
  27. if @objtype='P'
  28.  SET @fake_01='ALTER PROCEDURE '+ @procedure +' WITH ENCRYPTION AS select 1
  29.  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
  30. else if @objtype='FN'
  31.  SET @fake_01='ALTER FUNCTION '+ @procedure +'() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1
  32.  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/ END'
  33. else if @objtype='V'
  34.  SET @fake_01='ALTER view '+ @procedure +' WITH ENCRYPTION AS select 1 as col
  35.  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
  36. else if @objtype='TR'
  37.  SET @fake_01='ALTER trigger '+ @procedure +' ON '+@parentname+'WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10)
  38.  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
  39. EXECUTE (@fake_01)
  40. --从sys.sysobjvalues里提出加密的假的
  41. SET @fake_encrypt_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid =
  42. object_id(@procedure) and valclass = 1 order by subobjid )
  43. if @objtype='P'
  44.  SET @fake_01='Create PROCEDURE '+ @procedure +' WITH ENCRYPTION AS select 1
  45.  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
  46. else if @objtype='FN'
  47.  SET @fake_01='CREATE FUNCTION '+ @procedure +'() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1
  48.  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/ END'
  49. else if @objtype='V'
  50.  SET @fake_01='Create view '+ @procedure +' WITH ENCRYPTION AS select 1 as col
  51.  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
  52. else if @objtype='TR'
  53.  SET @fake_01='Create trigger '+ @procedure +' ON '+@parentname+'WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10)
  54.  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
  55. --开始计数
  56. SET @intProcSpace=1
  57. --使用字符填充临时变量
  58. SET @real_decrypt_01 = replicate(cast('A'as nvarchar(max)), (datalength(@real_01) /2 ))
  59. --循环设置每一个变量,创建真正的变量
  60. --每次一个字节
  61. SET @intProcSpace=1
  62. --如有必要,遍历每个@real_xx变量并解密
  63. WHILE @intProcSpace<=(datalength(@real_01)/2)
  64. BEGIN
  65. --真的和假的和加密的假的进行异或处理
  66. SET @real_decrypt_01 = stuff(@real_decrypt_01@intProcSpace1,
  67. NCHAR(UNICODE(substring(@real_01@intProcSpace1)) ^
  68. (UNICODE(substring(@fake_01@intProcSpace1)) ^
  69. UNICODE(substring(@fake_encrypt_01@intProcSpace1)))))
  70. SET @intProcSpace=@intProcSpace+1
  71. END
  72. --通过sp_helptext逻辑向表#output里插入变量
  73. insert #output (real_decrypt) select @real_decrypt_01
  74. --select real_decrypt AS '#output chek' from #output --测试
  75. -- -------------------------------------
  76. --开始从sp_helptext提取
  77. -- -------------------------------------
  78. declare @dbname sysname
  79. ,@BlankSpaceAdded int
  80. ,@BasePos int
  81. ,@CurrentPos int
  82. ,@TextLength int
  83. ,@LineId int
  84. ,@AddOnLen int
  85. ,@LFCR int --回车换行的长度
  86. ,@DefinedLength int
  87. ,@SyscomText nvarchar(max)
  88. ,@Line nvarchar(255)
  89. Select @DefinedLength = 255
  90. SELECT @BlankSpaceAdded = 0 --跟踪行结束的空格。注意Len函数忽略了多余的空格
  91. CREATE TABLE #CommentText
  92. (LineId int
  93. ,Text nvarchar(255) collate database_default)
  94. --使用#output代替sys.sysobjvalues
  95. DECLARE ms_crs_syscom CURSOR LOCAL
  96. FOR SELECT real_decrypt from #output
  97. ORDER BY ident
  98. FOR READ ONLY
  99. --获取文本
  100. SELECT @LFCR = 2
  101. SELECT @LineId = 1
  102. OPEN ms_crs_syscom
  103. FETCH NEXT FROM ms_crs_syscom into @SyscomText
  104. WHILE @@fetch_status >= 0
  105. BEGIN
  106. SELECT @BasePos = 1
  107. SELECT @CurrentPos = 1
  108. SELECT @TextLength = LEN(@SyscomText)
  109. WHILE @CurrentPos != 0
  110. BEGIN
  111. --通过回车查找行的结束
  112. SELECT @CurrentPos = CHARINDEX(char(13)+char(10), @SyscomText,
  113. @BasePos)
  114. --如果找到回车
  115. IF @CurrentPos != 0
  116. BEGIN
  117. --如果@Lines的长度的新值比设置的大就插入@Lines目前的内容并继续
  118. While (isnull(LEN(@Line),0) + @BlankSpaceAdded +
  119. @CurrentPos-@BasePos + @LFCR) > @DefinedLength
  120. BEGIN
  121. SELECT @AddOnLen = @DefinedLength-(isnull(LEN(@Line),0) +
  122. @BlankSpaceAdded)
  123. INSERT #CommentText VALUES
  124. @LineId,
  125. isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText,
  126. @BasePos@AddOnLen), N''))
  127. SELECT @Line = NULL, @LineId = @LineId + 1,
  128. @BasePos = @BasePos + @AddOnLen@BlankSpaceAdded = 0
  129. END
  130. SELECT @Line = isnull(@Line, N'') +
  131. isnull(SUBSTRING(@SyscomText@BasePos@CurrentPos-@BasePos + @LFCR), N'')
  132. SELECT @BasePos = @CurrentPos+2
  133. INSERT #CommentText VALUES( @LineId@Line )
  134. SELECT @LineId = @LineId + 1
  135. SELECT @Line = NULL
  136. END
  137. ELSE
  138. --如果回车没找到
  139. BEGIN
  140. IF @BasePos <= @TextLength
  141. BEGIN
  142. --如果@Lines长度的新值大于定义的长度
  143. While (isnull(LEN(@Line),0) + @BlankSpaceAdded +
  144. @TextLength-@BasePos+1 ) > @DefinedLength
  145. BEGIN
  146. SELECT @AddOnLen = @DefinedLength -
  147. (isnull(LEN(@Line),0) + @BlankSpaceAdded)
  148. INSERT #CommentText VALUES
  149. @LineId,
  150. isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText,
  151. @BasePos@AddOnLen), N''))
  152. SELECT @Line = NULL, @LineId = @LineId + 1,
  153. @BasePos = @BasePos + @AddOnLen@BlankSpaceAdded =
  154. 0
  155. END
  156. SELECT @Line = isnull(@Line, N'') +
  157. isnull(SUBSTRING(@SyscomText@BasePos@TextLength-@BasePos+1 ), N'')
  158. if LEN(@Line) < @DefinedLength and charindex(' ',
  159. @SyscomText@TextLength+1 ) > 0
  160. BEGIN
  161. SELECT @Line = @Line + ' ', @BlankSpaceAdded = 1
  162. END
  163. END
  164. END
  165. END
  166. FETCH NEXT FROM ms_crs_syscom into @SyscomText
  167. END
  168. IF @Line is NOT NULL
  169. INSERT #CommentText VALUES( @LineId@Line )
  170. select Text from #CommentText order by LineId
  171. CLOSE ms_crs_syscom
  172. DEALLOCATE ms_crs_syscom
  173. DROP TABLE #CommentText
  174. -- -------------------------------------
  175. --结束从sp_helptext提取
  176. -- -------------------------------------
  177. --删除用短横线创建的存储过程并重建原始的存储过程
  178. ROLLBACK TRAN
  179. DROP TABLE #output
  180. GO
  181. 启用DAC
  182. SP_CONFIGURE 'remote admin connections';
  183. GO
  184. ----0:仅允许本地连接使用 DAC,1:允许远程连接使用 DAC
  185. SP_CONFIGURE 'remote admin connections', 0;
  186. GO
  187. RECONFIGURE WITH OVERRIDE;
  188. GO

文件——>新建——>数据库引擎查询

服务器名称:admin:.或者admin:服务器名称

登录进去执行解密操作

  1. USE TEST
  2. EXEC Decryption P_TEST
  3. GO

SQLSERVER对加密的存储过程、视图、触发器进行解密

为了安全起见,不要在正式环境进行解密,避免在解密过程中将原存储过程损坏!

总结

以上所述是小编给大家介绍的SQLSERVER对加密的存储过程、视图、触发器进行解密,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对飞鱼技术博客的支持!