一、存储过程加密
本方法可用于加密SQL存储过程、函数或者触发器
使用 WITH ENCRYPTION 选项:WITH ENCRYPTION 子句对用户隐藏存储过程的文本
例子:
IF OBJECT_ID(N'[Pro_Encrypt_Test]') IS NOT NULL DROP PROCEDURE [Pro_Encrypt_Test] GO CREATE PROCEDURE [Pro_Encrypt_Test] WITH ENCRYPTION AS BEGIN SELECT * FROM T_TEST END GO
建好存储过程后,用下面的语句查看存储过程
EXEC sp_helptext Pro_Encrypt_Test
结果是:
The text for object 'Pro_Encrypt_Test' is encrypted.
把存储过程加密后,可以不让别人在数据库中直接看到存储过程的内容。
当然网上存在不少解密的方法,所以这样的加密不是真正安全的,只是增加别人查看存储过程的难度而已。
二、存储过程解密
IF OBJECT_ID ( N'SP_SQLJM2008', N'P' ) IS NOT NULL DROP PROCEDURE SP_SQLJM2008 GO CREATE PROCEDURE SP_SQLJM2008 ( @ObjectName VARCHAR(50) ) WITH ENCRYPTION AS BEGIN SET NOCOUNT ON --------------------------- CSDN:j9988 copyright:2004.01.05 --------------------------- V3.1 --------------------------- 破解字节不受限制,适用于SQLSERVER2000, SQLSERVER2005存储过程,函数,视图,触发器 --------------------------- 发现有错,请E_MAIL:CSDNj9988@tom.com --------------------------- 整理SQLSERVER2000、注释:郭长海 --------------------------- 整理SQLSERVER2005、注释:郭长海 --------------------------- 整理SQLSERVER2008、注释:郭长海 DECLARE @Version CHAR(4), @ObjectID INT DECLARE @n INT, @j INT, @k INT, @i_copy INT DECLARE @colid INT, @encrypted INT, @MaxNumber INT DECLARE @ExecSqlTxt NVARCHAR (4000), @TestSqlTxt NVARCHAR (4000), @CHR NVARCHAR(4000) DECLARE @OrigSpText1 NVARCHAR (4000), @OrigSpText2 NVARCHAR (4000), @OrigSpText3 NVARCHAR (4000), @ResultSql NVARCHAR (4000), @ResultLen INT DECLARE @i INT, @status INT, @type VARCHAR ( 10 ), @parentid INT DECLARE @ConnectText NVARCHAR (4000), @PrintText NVARCHAR (4000), @Pos INT, @Temp INT, @Line INT ------------------------------------------------------------------------------------------------------------ SELECT @ObjectID = OBJECT_ID ( @ObjectName ) SELECT @type = xtype, @parentid = parent_obj FROM SYSOBJECTS WHERE ID = @ObjectID SELECT @Version = CASE WHEN SUBSTRING(@@Version, 1, 30) LIKE '%2000%' THEN '2000' WHEN SUBSTRING(@@Version, 1, 30) LIKE '%2005%' THEN '2005' WHEN SUBSTRING(@@Version, 1, 30) LIKE '%2008%' THEN '2008' END IF @Version NOT IN ('2000', '2005', '2008') RETURN BEGIN TRAN SELECT id, number, colid, ctext, encrypted, status INTO #TempSysComments1 FROM SYSCOMMENTS WHERE ID = @ObjectID SELECT @MaxNumber = MAX ( number ) FROM #TempSysComments1 IF @Version IN ('2005', '2008') BEGIN SET @i_copy = 1 WHILE EXISTS(SELECT colid FROM #TempSysComments1 WHERE colid = @i_copy) BEGIN UPDATE #TempSysComments1 SET ctext = (SELECT TOP 1 SUBSTRING(imageval, (@i_copy - 1)*8000 + 1, 8000) FROM sys.sysobjvalues WHERE objid = @ObjectID AND valclass = 1 ORDER BY subobjid ) WHERE colid = @i_copy SET @i_copy = @i_copy + 1 END END ------ 设计同名测试明文,创建测试密文。 SET @k = 0 WHILE @k <= @MaxNumber BEGIN IF EXISTS ( SELECT 1 FROM SYSCOMMENTS WHERE ID = @ObjectID AND number = @k ) BEGIN ------ 设计测试 ALTER 明文 IF @type = 'P' SET @TestSqlTxt = ( CASE WHEN @MaxNumber > 1 THEN 'ALTER PROCEDURE ' + @ObjectName + ';' + RTRIM ( @k ) + ' WITH ENCRYPTION AS ' ELSE 'ALTER PROCEDURE ' + @ObjectName + ' WITH ENCRYPTION AS ' END ) IF @type = 'TR' SET @TestSqlTxt = 'ALTER TRIGGER ' + @ObjectName + ' ON ' + OBJECT_NAME ( @parentid ) + ' WITH ENCRYPTION FOR INSERT AS PRINT 1 ' IF @type = 'FN' OR @type = 'TF' OR @type = 'IF' SET @TestSqlTxt = ( CASE @type WHEN 'TF' THEN 'ALTER FUNCTION ' + @ObjectName + ' ( @a CHAR ( 1 ) ) RETURNS @b TABLE ( a VARCHAR ( 10 ) ) WITH ENCRYPTION AS BEGIN INSERT @b SELECT @a RETURN END' WHEN 'FN' THEN 'ALTER FUNCTION ' + @ObjectName + ' ( @a CHAR ( 1 ) ) RETURNS CHAR ( 1 ) WITH ENCRYPTION AS BEGIN RETURN @a END' WHEN 'IF' THEN 'ALTER FUNCTION ' + @ObjectName + ' ( @a CHAR ( 1 ) ) RETURNS TABLE WITH ENCRYPTION AS RETURN SELECT @a AS a' END ) IF @type = 'V' SET @TestSqlTxt = 'ALTER VIEW ' + @ObjectName + ' WITH ENCRYPTION AS SELECT 1 AS f' --------------------------------------------------------------------------- ------ 创建测试密文 SET @CHR = REPLICATE(N'-', 4000) SET @ExecSqlTxt = N'EXEC(@SQL' SELECT @ExecSqlTxt = @ExecSqlTxt + N'+@' FROM #TempSysComments1 WHERE ID = @ObjectID SET @ExecSqlTxt = @ExecSqlTxt + N')' EXEC sp_executesql @ExecSqlTxt, N'@SQL NVARCHAR(4000), @ NVARCHAR(4000)', @SQL = @TestSqlTxt, @ = @CHR SELECT id, number, colid, ctext, encrypted, status INTO #TempSysComments2 FROM SYSCOMMENTS WHERE ID = @ObjectID IF @Version IN ('2005', '2008') BEGIN SET @i_copy = 1 WHILE EXISTS(SELECT colid FROM #TempSysComments2 WHERE colid = @i_copy) BEGIN UPDATE #TempSysComments2 SET ctext = (SELECT TOP 1 SUBSTRING(imageval, (@i_copy - 1)*8000 + 1, 8000) FROM sys.sysobjvalues WHERE objid = @ObjectID AND valclass = 1 ORDER BY subobjid ) WHERE ID = @ObjectID AND colid = @i_copy SET @i_copy = @i_copy + 1 END END SELECT id, number, colid, ctext, encrypted, status INTO #TempSysComments3 FROM SYSCOMMENTS WHERE ID = @ObjectID UPDATE #TempSysComments3 SET ctext = CONVERT(VARBINARY(8000), CONVERT(NVARCHAR(4000), REPLICATE('-', 8000))) WHERE ID = @ObjectID UPDATE #TempSysComments3 SET ctext = CONVERT(VARBINARY(8000), CONVERT(NVARCHAR(4000), REPLACE(@TestSqlTxt,'ALTER','CREATE') + REPLICATE('-', 8000))) WHERE ID = @ObjectID AND colid = 1 END SET @k = @k + 1 END ------------------------------------------------------------------------------------------------------------ ------ 由测试明文与测试密文进行异或运算得出密匙,由密匙与原密文进行异或运算得出原明文。 ------ 取测试密文 SET @Line = 0 SET @ConnectText = N'' SET @k = 0 WHILE @k <= @MaxNumber BEGIN IF EXISTS ( SELECT 1 FROM SYSCOMMENTS WHERE ID = @ObjectID AND number = @k ) BEGIN SELECT @colid = MAX ( colid ) FROM #TempSysComments1 WHERE ID = @ObjectID AND number = @k SET @n = 1 WHILE @n <= @colid BEGIN ------ 取原文密文 SELECT @OrigSpText1 = ctext, @encrypted = encrypted, @status = status FROM #TempSysComments1 WHERE ID = @ObjectID AND colid = @n AND number = @k IF @encrypted = 1 BEGIN ------ 取测试密文 SELECT @OrigSpText2 = ctext FROM #TempSysComments2 WHERE ID = @ObjectID AND colid = @n AND number = @k ------ 取测试明文 SELECT @OrigSpText3 = ctext FROM #TempSysComments3 WHERE ID = @ObjectID AND colid = @n AND number = @k SET @ResultSql = N'' SET @ResultLen = DATALENGTH ( @OrigSpText1 ) / 2 SET @i = 1 WHILE @i <= @ResultLen BEGIN SET @ResultSql = @ResultSql + NCHAR(UNICODE(SUBSTRING(@OrigSpText1, @i, 1 )) ^ UNICODE(SUBSTRING(@OrigSpText2, @i, 1 )) ^ UNICODE(SUBSTRING(@OrigSpText3, @i, 1 ))) SET @i = @i + 1 END END ELSE BEGIN SELECT @ResultSql = CONVERT ( NVARCHAR (4000), CASE WHEN @status & 2 = 2 THEN uncompress ( ctext ) ELSE ctext END ) FROM #TempSysComments1 WHERE ID = @ObjectID AND colid = @n AND number = @k END ------------------------------------------------------------------ ---- 对解密后的文件进行显示格式还原 SET @Temp = 1 SET @Pos = 0 WHILE @Temp > 0 BEGIN SET @Temp = CHARINDEX(NCHAR(13)+NCHAR(10), @ResultSql) IF @Temp > 0 BEGIN SET @PrintText = SUBSTRING (@ResultSql, 1, @Temp - 1) SET @PrintText = ISNULL (@PrintText, '') SET @ResultSql = SUBSTRING (@ResultSql, @Temp + 2, LEN(@ResultSql) - LEN(@PrintText) - 2) SET @ResultSql = ISNULL (@ResultSql, '') IF @Pos = 0 BEGIN SET @PrintText = @ConnectText + @PrintText SET @ConnectText = N'' END SET @Pos = CHARINDEX(NCHAR(13)+NCHAR(10), @PrintText) IF @Pos > 0 BEGIN SET @ResultSql = SUBSTRING (@PrintText, @Pos + 2, LEN(@PrintText) - @Pos - 1) + NCHAR(13) + NCHAR(10) + @ResultSql SET @PrintText = SUBSTRING (@PrintText, 1, @Pos - 1) END IF @Version IN ('2005', '2008') BEGIN SET @Line = (@Line + 10) / 10 * 10 SET @PrintText = REPLACE(@PrintText, N' ', N'^=*') WHILE LEN(@PrintText) > 0 BEGIN IF LEN(@PrintText) > 100 BEGIN PRINT RIGHT(N'0000000000' + CONVERT(NVARCHAR(10), @Line), 10 ) + SUBSTRING(@PrintText, 1, 100) SET @PrintText = SUBSTRING(@PrintText, 101, LEN(@PrintText) - 100) SET @Line = @Line + 1 END ELSE BEGIN PRINT RIGHT(N'0000000000' + CONVERT(NVARCHAR(10), @Line), 10 ) + @PrintText SET @PrintText = '' SET @Line = @Line + 1 END END END IF @Version = '2000' PRINT @PrintText SET @Pos = 1 END ELSE BEGIN SET @ConnectText = @ConnectText + @ResultSql SET @Temp = CHARINDEX(NCHAR(13)+NCHAR(10), @ConnectText) IF @Temp > 0 BEGIN SET @ResultSql = @ConnectText SET @ConnectText = N'' END END END ------------------------------------------------------------------ SET @n = @n + 1 END END SET @k = @k + 1 END IF @Version IN ('2005', '2008') BEGIN SET @PrintText = @ConnectText SET @PrintText = REPLACE(@PrintText, N' ', N'^=*') IF LEN(@PrintText) > 0 SET @Line = (@Line + 10) / 10 * 10 WHILE LEN(@PrintText) > 0 BEGIN IF LEN(@PrintText) > 100 BEGIN PRINT RIGHT(N'0000000000' + CONVERT(NVARCHAR(10), @Line), 10 ) + SUBSTRING(@PrintText, 1, 100) SET @PrintText = SUBSTRING(@PrintText, 101, LEN(@PrintText) - 100) SET @Line = @Line + 1 END ELSE BEGIN PRINT RIGHT(N'0000000000' + CONVERT(NVARCHAR(10), @Line), 10 ) + @PrintText SET @PrintText = '' SET @Line = @Line + 1 END END END IF @Version = '2000' PRINT @ConnectText ------------------------------------------------------------------------------------------------------------ DROP TABLE #TempSysComments1 DROP TABLE #TempSysComments2 DROP TABLE #TempSysComments3 ROLLBACK TRAN END --------------------------------------------------------------------------------------------------------------------------- GO IF OBJECT_ID ( N'SP_SQLJM', N'P' ) IS NOT NULL DROP PROCEDURE SP_SQLJM GO CREATE PROCEDURE SP_SQLJM ( @ObjectName VARCHAR(50) ) WITH ENCRYPTION AS BEGIN DECLARE @dossqlcmd VARCHAR(8000) DECLARE @SQL_PRINT NVARCHAR(4000) DECLARE @SQL_SYNTAX NVARCHAR(4000) DECLARE @Version CHAR(4) DECLARE @Line INT SELECT @Version = CASE WHEN SUBSTRING(@@Version, 1, 30) LIKE '%2000%' THEN '2000' WHEN SUBSTRING(@@Version, 1, 30) LIKE '%2005%' THEN '2005' WHEN SUBSTRING(@@Version, 1, 30) LIKE '%2008%' THEN '2008' END IF @Version IN ('2005', '2008') BEGIN ---- SELECT @dossqlcmd = 'sqlcmd -S '+RTRIM(ps.hostname)+' -d '+db.name+' -U '+@DBUser+' -P '+@DBPass+' -A -q "EXEC SP_JM1 ''' + @ObjectName + '''"' SELECT @dossqlcmd = 'sqlcmd -A -q "EXEC '+db.name+'..SP_SQLJM2008 ''' + @ObjectName + '''"' FROM master..sysprocesses ps, master..sysdatabases db WHERE ps.spid = @@spid AND ps.dbid = db.dbid IF OBJECT_ID('tempdb..#TEMP_SYNTAX') IS NOT NULL DROP TABLE #TEMP_SYNTAX CREATE TABLE #TEMP_SYNTAX ( ctext NVARCHAR (4000) ) INSERT INTO #TEMP_SYNTAX( ctext ) EXEC master..xp_cmdshell @dossqlcmd SET @Line = 10 SET @SQL_PRINT = N'' ----- select * from #TEMP_SYNTAX where ISNUMERIC ( SUBSTRING(ctext, 1, 10) ) = 0 ORDER BY ctext DECLARE CUR_SYNTAX CURSOR FOR SELECT ISNULL(ctext, N'') FROM #TEMP_SYNTAX WHERE ctext IS NOT NULL ORDER BY ctext OPEN CUR_SYNTAX FETCH NEXT FROM CUR_SYNTAX INTO @SQL_SYNTAX WHILE @@FETCH_STATUS = 0 BEGIN IF ISNUMERIC ( SUBSTRING(@SQL_SYNTAX, 1, 10) ) = 1 BEGIN IF CONVERT(INT, SUBSTRING(@SQL_SYNTAX, 1, 10)) % 10 = 0 BEGIN SET @SQL_PRINT = REPLACE(@SQL_PRINT, N'^=*', N' ') IF LEN(@SQL_PRINT) > 0 PRINT @SQL_PRINT SET @SQL_PRINT = SUBSTRING(@SQL_SYNTAX, 11, LEN(@SQL_SYNTAX) - 10) END ELSE BEGIN IF LEN(@SQL_SYNTAX) > 10 SET @SQL_PRINT = @SQL_PRINT + SUBSTRING(@SQL_SYNTAX, 11, LEN(@SQL_SYNTAX) - 10) END END FETCH NEXT FROM CUR_SYNTAX INTO @SQL_SYNTAX END SET @SQL_PRINT = REPLACE(@SQL_PRINT, N'^=*', N' ') IF LEN(@SQL_PRINT) > 0 PRINT @SQL_PRINT CLOSE CUR_SYNTAX DEALLOCATE CUR_SYNTAX IF OBJECT_ID('tempdb..#TEMP_SYNTAX') IS NOT NULL DROP TABLE #TEMP_SYNTAX END IF @Version = '2000' BEGIN EXEC SP_SQLJM2008 @ObjectName END END GO ---- 调用解密对象 ---- 如果提示“SQL Server 阻止了对组件 'xp_cmdshell' 的 过程'sys.xp_cmdshell' 的访问。”,则执行下面的代码。 /* EXEC sp_configure 'xp_cmdshell', 1 RECONFIGURE */ ---- 如果提示“配置选项 'xp_cmdshell' 不存在,也可能是高级选项。”,则执行下面的代码。 /* EXEC sp_configure 'show advanced options', 1 RECONFIGURE */ EXEC SP_SQLJM 'Up_HANDle_Stock'
摘自: