当前位置:网站首页>对存储过程进行加密和解密(SQL 2008/SQL 2012)
对存储过程进行加密和解密(SQL 2008/SQL 2012)
2022-07-07 07:45:00 【蝈蝈(GuoGuo)】
开始:
在网络上,看到有SQL Server 2000和SQL Server 2005 的存储过程加密和解密的方法,后来分析了其中的代码,发现它们的原理都是一样的。后来自己根据实际的应用环境,编写了两个存储过程,一个加密存储过程(sp_EncryptObject),和一个解密存储过程(sp_EncryptObject),它们可以应用于SQL Server中的储过程,函数,视图,以及触发器。
感觉这两个存储过程蛮有意思的,拿来与大家分享;如果你看过类似的,就当作重温一下也好。
用于加密的存储过程 (sp_EncryptObject) :
存储过程(sp_EncryptObject)加密的方法是在存储过程,函数,视图的“As”位置前加上“with encryption”;如果是触发器,就在“for”位置前加“with encryption”。
如果触发器是{ AFTER | INSTEAD OF} 需要修改下面代码"For"位置:
if objectproperty(object_id(@Object),'ExecIsAfterTrigger')=0 set @Replace='As' ; else set @Replace='For ';
存储过程完成代码:
View Code
如果SQL Server 2012,请修改下面两个位置的代码。在SQL Server 2012,建议在使用throw来代替raiserror。
解密方法:
解密过程,最重要采用异或方法:
[字符1]经过函数 fn_x(x)加密变成[加密后字符1],如果我们已知[加密后字符1],反过来查[字符1],可以这样:
[字符1] = [字符2] ^ fn_x([字符2]) ^ [加密后字符1]
这里我列举一个简单的例子:
--创建加密函数(fn_x) if object_id('fn_x') is not null drop function fn_x go create function fn_x ( @x nchar(1) )returns nchar(1) as begin return(nchar((65535-unicode(@x)))) end go declare @nchar_1_encrypt nchar(1),@nchar_2 nchar(1) --对字符'A'进行加密,存入变量@nchar_1_encrypt set @nchar_1_encrypt=dbo.fn_x(N'A') --參考的字符@nchar_2 set @nchar_2='x' --算出@nchar_1_encrypt 加密前的字符 select nchar(unicode(@nchar_2)^unicode(dbo.fn_x(@nchar_2))^unicode(@nchar_1_encrypt)) as [@nchar_1] /* @nchar_1 -------------------- A */
[注]: 从SQL Server 2000至 SQL Server 2012 采用异或方法都可以解密
用于解密的存储过程(sp_DecryptObject):
Use master Go if object_ID('[sp_DecryptObject]') is not null Drop Procedure [sp_DecryptObject] Go create procedure sp_DecryptObject ( @Object sysname, --要解密的对象名:函数,存储过程,视图或触发器 @MaxLength int=4000 --评估内容的长度 ) as set nocount on /* 1. 解密 */ if not exists(select 1 from sys.objects a where a.object_id=object_id(@Object) And a.type in('P','V','TR','FN','IF','TF')) begin --SQL Server 2008 raiserror 50001 N'无效的对象!要解密的对象必须是函数,存储过程,视图或触发器。' --SQL Server 2012 --throw 50001, N'无效的对象!要解密的对象必须是函数,存储过程,视图或触发器。',1 return end if exists(select 1 from sys.sql_modules a where a.object_id=object_id(@Object) and a.definition is not null) begin --SQL Server 2008 raiserror 50001 N'对象没有加密!' --SQL Server 2012 --throw 50001, N'无效的对象!要解密的对象必须是函数,存储过程,视图或触发器。',1 return end declare @sql nvarchar(max) --解密出来的SQL语句 ,@imageval nvarchar(max) --加密字符串 ,@tmpStr nvarchar(max) --临时SQL语句 ,@tmpStr_imageval nvarchar(max) --临时SQL语句(加密后) ,@type char(2) --对象类型('P','V','TR','FN','IF','TF') ,@objectID int --对象ID ,@i int --While循环使用 ,@Oject1 nvarchar(1000) set @objectID=object_id(@Object) set @type=(select a.type from sys.objects a where [email protected]) declare @Space4000 nchar(4000) set @Space4000=replicate('-',4000) /* @tmpStr 会构造下面的SQL语句 ------------------------------------------------------------------------------- alter trigger Tr_Name on Table_Name with encryption for update as return /**/ alter proc Proc_Name with encryption as select 1 as col /**/ alter view View_Name with encryption as select 1 as col /**/ alter function Fn_Name() returns int with encryption as begin return(0) end/**/ */ set @Oject1=quotename(object_schema_name(@objectID))+'.'+quotename(@Object) set @tmpStr= case when @type ='P ' then N'Alter Procedure '[email protected]+' with encryption as select 1 as column1 ' when @type ='V ' then N'Alter View '[email protected]+' with encryption as select 1 as column1 ' when @type ='FN' then N'Alter Function '[email protected]+'() returns int with encryption as begin return(0) end ' when @type ='IF' then N'Alter Function '[email protected]+'() returns table with encryption as return(Select a.name from sys.types a) ' when @type ='TF' then N'Alter Function '[email protected]+'() returns @t table(name nvarchar(50)) with encryption as begin return end ' else 'Alter Trigger '[email protected]+'on '+quotename(object_schema_name(@objectID))+'.'+(select Top(1) quotename(object_name(parent_id)) from sys.triggers a where [email protected])+' with encryption for update as return ' end set @[email protected]+'/*'[email protected] set @i=0 while @i < (ceiling(@MaxLength*1.0/4000)-1) begin set @[email protected]+ @Space4000 Set @[email protected]+1 end set @[email protected]+'*/' ------------ set @imageval =(select top(1) a.imageval from sys.sysobjvalues a where [email protected] and a.valclass=1) begin tran exec(@tmpStr) set @tmpStr_imageval =(select top(1) a.imageval from sys.sysobjvalues a where [email protected] and a.valclass=1) rollback tran ------------- set @tmpStr=stuff(@tmpStr,1,5,'create') set @sql='' set @i=1 while @i<= (datalength(@imageval)/2) begin set @[email protected]+isnull(nchar(unicode(substring(@tmpStr,@i,1)) ^ unicode(substring(@tmpStr_imageval,@i,1))^unicode(substring(@imageval,@i,1)) ),'') Set @i+=1 end /* 2. 列印 */ declare @patindex int while @sql>'' begin set @patindex=patindex('%'+char(13)+char(10)+'%',@sql) if @patindex >0 begin print substring(@sql,1,@patindex-1) set @sql=stuff(@sql,1,@patindex+1,'') end else begin set @patindex=patindex('%'+char(13)+'%',@sql) if @patindex >0 begin print substring(@sql,1,@patindex-1) set @sql=stuff(@sql,1,@patindex,'') end else begin set @patindex=patindex('%'+char(10)+'%',@sql) if @patindex >0 begin print substring(@sql,1,@patindex-1) set @sql=stuff(@sql,1,@patindex,'') end else begin print @sql set @sql='' end end end end Go exec sp_ms_marksystemobject 'sp_DecryptObject' --标识为系统对象 go
如果SQL Server 2012,请修改下面两个位置的代码。方法类似于前面的加密过程:
搭建测试环境:
在一个测试环境中(DB: Test),先执行上面的加密存储过程(sp_EncryptObject)和解密存储过程(sp_EncryptObject);再创建两个表:TableA & TableB
use test go --创建表: TableA & TableB if object_id('myTableA') is not null drop table myTableA if object_id('myTableB') is not null drop table myTableB go create table myTableA (ID int identity,data nvarchar(50),constraint PK_myTableA primary key(ID)) create table myTableB (ID int ,data nvarchar(50),constraint PK_myTableB primary key(ID)) go
接下来,我们要创建6个未加密的对象(对象类型包含 'P','V','TR','FN','IF','TF'):
1.视图(myView):
View Code
2.触发器(MyTrigger):
View Code
3.存储过程(MyProc):
View Code
4.用户定义表值函数(TF)(MyFunction_TF):
View Code
5.内联表值函数(IF) (MyFunction_IF):
View Code
6.标量函数(FN)(MyFunction_FN):
View Code
当执行完了上面的1-6步骤的脚本,我们通过查询系统视图sys.sql_modules,可以看到未加密前的定义信息:
select b.name as object,b.type,a.definition from sys.sql_modules a inner join sys.objects b on b.object_id=a.object_id where b.create_date>=convert(date,getdate()) order by b.object_id
加密测试:
下面我就通过调用加密存储过程(sp_EncryptObject),一次性对它们进行加密:
use test go exec sp_EncryptObject 'all' go
当我们再查回系统视图sys.sql_modules,会发现definition列返回的是null值,说明定义内容已经给加密:
解密测试:
解密过程,必须在DAC连接SQL Server,我们这里例子是从 SSMS(SQL Server Management Studio) 查询编辑器启动 DAC,如图:
解密存储过程(sp_DecryptObject),只能一次对一个存储过程、函数、视图或触发器,进行解密:
use test go exec sp_DecryptObject MyTrigger go
当定义内容长度超过4000,我们可以指定@MaxLength的值,如:
exec sp_DecryptObject fn_My,20000 go
这里(fn_My)是一个函数,定义内容超过了8000:
... ...
小结:
虽然,上面的脚本,我已经在SQL Server 2008 R2 和SQL Server 2012测试过,但无法避免一些未知错误 。如果你自己在测试上面的脚本,请不要在生产环境上。如果你在应用过程,碰到有什么问题或有什么意见和建议可以发email联系我或跟帖,在此非常感谢!
边栏推荐
- Official media attention! The list of top 100 domestic digital collection platforms was released, and the industry accelerated the healthy development of compliance
- The method of word automatically generating directory
- STM32基础知识—内存映射
- Three years after graduation
- Guid主键
- Some test points about coupon test
- Before joining the chain home, I made a competitive product analysis for myself
- Introduction to automated testing framework
- Applet popup half angle mask layer
- Enterprise practice | construction of banking operation and maintenance index system under complex business relations
猜你喜欢
AI moves from perception to intelligent cognition
ORM模型--数据记录的创建操作,查询操作
Google Colab装载Google Drive(Google Colab中使用Google Drive)
XML配置文件解析与建模
嵌入式背景知识-芯片
ISP、IAP、ICP、JTAG、SWD的编程特点
Garbage disposal method based on the separation of smart city and storage and living digital home mode
一大波开源小抄来袭
Memory ==c language 1
A wave of open source notebooks is coming
随机推荐
conda离线创建虚拟环境
Sword finger offer II 107 Distance in matrix
网上可以开炒股账户吗安全吗
Parameter sniffing (2/2)
ORM -- grouping query, aggregation query, query set queryset object properties
Gym - 102219j kitchen plates (violent or topological sequence)
终于可以一行代码也不用改了!ShardingSphere 原生驱动问世
arcgis操作:dwg数据转为shp数据
ORM model -- creation and query of data records
Win10 installation vs2015
Official media attention! The list of top 100 domestic digital collection platforms was released, and the industry accelerated the healthy development of compliance
Future development blueprint of agriculture and animal husbandry -- vertical agriculture + artificial meat
Postman interface test VI
Advanced function learning in ES6
中国首款电音音频类“山野电音”数藏发售来了!
字节跳动 Kitex 在森马电商场景的落地实践
Postman interface test II
内存==c语言1
一大波开源小抄来袭
Enterprise practice | construction of banking operation and maintenance index system under complex business relations