国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

Mysql|Sql Server|Oracle|Redis|MongoDB|PostgreSQL|Sqlite|DB2|mariadb|Access|數(shù)據(jù)庫(kù)技術(shù)|

服務(wù)器之家 - 數(shù)據(jù)庫(kù) - Sql Server - SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析

SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析

2020-06-11 17:44服務(wù)器之家 Sql Server

在網(wǎng)絡(luò)上,看到有SQL Server 2000和SQL Server 2005 的存儲(chǔ)過(guò)程加密和解密的方法,后來(lái)分析了其中的代碼,發(fā)現(xiàn)它們的原理都是一樣的;感覺(jué)這兩個(gè)存儲(chǔ)過(guò)程蠻有意思的,拿來(lái)與大家分享,需要了解的朋友可以參考下

開(kāi)始
--------------------------------------------------------------------------------
在網(wǎng)絡(luò)上,看到有SQL Server 2000和SQL Server 2005 的存儲(chǔ)過(guò)程加密和解密的方法,后來(lái)分析了其中的代碼,發(fā)現(xiàn)它們的原理都是一樣的。后來(lái)自己根據(jù)實(shí)際的應(yīng)用環(huán)境,編寫(xiě)了兩個(gè)存儲(chǔ)過(guò)程,一個(gè)加密存儲(chǔ)過(guò)程(sp_EncryptObject),和一個(gè)解密存儲(chǔ)過(guò)程(sp_EncryptObject),它們可以應(yīng)用于SQL Server中的儲(chǔ)過(guò)程,函數(shù),視圖,以及觸發(fā)器。
感覺(jué)這兩個(gè)存儲(chǔ)過(guò)程蠻有意思的,拿來(lái)與大家分享;如果你看過(guò)類似的,就當(dāng)作重溫一下也好。
用于加密的存儲(chǔ)過(guò)程 (sp_EncryptObject) :
--------------------------------------------------------------------------------
存儲(chǔ)過(guò)程(sp_EncryptObject)加密的方法是在存儲(chǔ)過(guò)程,函數(shù),視圖的“As”位置前加上“with encryption”;如果是觸發(fā)器,就在“for”位置前加“with encryption”。
如果觸發(fā)器是{ AFTER | INSTEAD OF} 需要修改下面代碼"For"位置:

復(fù)制代碼 代碼如下:


if objectproperty(object_id(@Object),'ExecIsAfterTrigger')=0 set @Replace='As' ; else set @Replace='For ';


存儲(chǔ)過(guò)程完成代碼:

復(fù)制代碼 代碼如下:


Use master
Go
if object_ID('[sp_EncryptObject]') is not null
Drop Procedure [sp_EncryptObject]
Go
create procedure sp_EncryptObject
(
@Object sysname='All'
)
as
/*
當(dāng)@Object=All的時(shí)候,對(duì)所有的函數(shù),存儲(chǔ)過(guò)程,視圖和觸發(fā)器進(jìn)行加密
調(diào)用方法:
. Execute sp_EncryptObject 'All'
. Execute sp_EncryptObject 'ObjectName'
*/
begin
set nocount on
if @Object <>'All'
begin
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'無(wú)效的加密對(duì)象!加密對(duì)象必須是函數(shù),存儲(chǔ)過(guò)程,視圖或觸發(fā)器。'
--SQL Server 2012
--throw 50001, N'無(wú)效的加密對(duì)象!加密對(duì)象必須是函數(shù),存儲(chǔ)過(guò)程,視圖或觸發(fā)器。',1
return
end
if exists(select 1 from sys.sql_modules a where a.object_id=object_id(@Object) and a.definition is null)
begin
--SQL Server 2008
raiserror 50001 N'對(duì)象已經(jīng)加密!'
--SQL Server 2012
--throw 50001, N'對(duì)象已經(jīng)加密!',1
return
end
end
declare @sql nvarchar(max),@C1 nchar(1),@C2 nchar(1),@type nvarchar(50),@Replace nvarchar(50)
set @C1=nchar(13)
set @C2=nchar(10)
declare cur_Object
cursor for
select object_name(a.object_id) As ObjectName,a.definition
from sys.sql_modules a
inner join sys.objects b on b.object_id=a.object_id
and b.is_ms_shipped=0
and not exists(select 1
from sys.extended_properties x
where x.major_id=b.object_id
and x.minor_id=0
and x.class=1
and x.name='microsoft_database_tools_support'
)
where b.type in('P','V','TR','FN','IF','TF')
and (b.name=@Object or @Object='All')
and b.name <>'sp_EncryptObject'
and a.definition is not null
order by Case
when b.type ='V' then 1
when b.type ='TR' then 2
when b.type in('FN','IF','TF') then 3
else 4 end,b.create_date,b.object_id
open cur_Object
fetch next from cur_Object into @Object,@sql
while @@fetch_status=0
begin
Begin Try
if objectproperty(object_id(@Object),'ExecIsAfterTrigger')=0 set @Replace='As' ; else set @Replace='For ';
if (patindex('%'+@C1+@C2+@Replace+@C1+@C2+'%',@sql)>0)
begin
set @sql=Replace(@sql,@C1+@C2+@Replace+@C1+@C2,@C1+@C2+'With Encryption'+@C1+@C2+@Replace+@C1+@C2)
end
else if(patindex('%'+@C1+@Replace+@C1+'%',@sql)>0)
begin
set @sql=Replace(@sql,@C1+@Replace+@C1,@C1+'With Encryption'+@C1+@Replace+@C1)
end
else if(patindex('%'+@C2+@Replace+@C2+'%',@sql)>0)
begin
set @sql=Replace(@sql,@C2+@Replace+@C2,@C2+'With Encryption'+@C2+@Replace+@C2)
end
else if(patindex('%'+@C2+@Replace+@C1+'%',@sql)>0)
begin
set @sql=Replace(@sql,@C2+@Replace+@C1,@C1+'With Encryption'+@C2+@Replace+@C1)
end
else if(patindex('%'+@C1+@C2+@Replace+'%',@sql)>0)
begin
set @sql=Replace(@sql,@C1+@C2+@Replace,@C1+@C2+'With Encryption'+@C1+@C2+@Replace)
end
else if(patindex('%'+@C1+@Replace+'%',@sql)>0)
begin
set @sql=Replace(@sql,@C1+@Replace,@C1+'With Encryption'+@C1+@Replace)
end
else if(patindex('%'+@C2+@Replace+'%',@sql)>0)
begin
set @sql=Replace(@sql,@C2+@Replace,@C2+'With Encryption'+@C2+@Replace)
end
set @type =
case
when object_id(@Object,'P')>0 then 'Proc'
when object_id(@Object,'V')>0 then 'View'
when object_id(@Object,'TR')>0 then 'Trigger'
when object_id(@Object,'FN')>0 or object_id(@Object,'IF')>0 or object_id(@Object,'TF')>0 then 'Function'
end
set @sql=Replace(@sql,'Create '+@type,'Alter '+@type)
Begin Transaction
exec(@sql)
print N'已完成加密對(duì)象('+@type+'):'+@Object
Commit Transaction
End Try
Begin Catch
Declare @Error nvarchar(2047)
Set @Error='Object: '+@Object+@C1+@C2+'Error: '+Error_message()
Rollback Transaction
print @Error
print @sql
End Catch
fetch next from cur_Object into @Object,@sql
end
close cur_Object
deallocate cur_Object
end
Go
exec sp_ms_marksystemobject 'sp_EncryptObject' --標(biāo)識(shí)為系統(tǒng)對(duì)象
go


如果SQL Server 2012,請(qǐng)修改下面兩個(gè)位置的代碼。在SQL Server 2012,建議在使用throw來(lái)代替raiserror。
SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析 
解密方法
解密過(guò)程,最重要采用異或方法:
[字符1]經(jīng)過(guò)函數(shù) fn_x(x)加密變成[加密后字符1],如果我們已知[加密后字符1],反過(guò)來(lái)查[字符1],可以這樣:
[字符1] = [字符2] ^ fn_x([字符2]) ^ [加密后字符1]
這里我列舉一個(gè)簡(jiǎn)單的例子:

復(fù)制代碼 代碼如下:


--創(chuàng)建加密函數(shù)(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)
--對(duì)字符'A'進(jìn)行加密,存入變量@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 采用異或方法都可以解密
用于解密的存儲(chǔ)過(guò)程(sp_DecryptObject):

復(fù)制代碼 代碼如下:


Use master
Go
if object_ID('[sp_DecryptObject]') is not null
Drop Procedure [sp_DecryptObject]
Go
create procedure sp_DecryptObject
(
@Object sysname, --要解密的對(duì)象名:函數(shù),存儲(chǔ)過(guò)程,視圖或觸發(fā)器
@MaxLength int=4000 --評(píng)估內(nèi)容的長(zhǎng)度
)
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'無(wú)效的對(duì)象!要解密的對(duì)象必須是函數(shù),存儲(chǔ)過(guò)程,視圖或觸發(fā)器。'
--SQL Server 2012
--throw 50001, N'無(wú)效的對(duì)象!要解密的對(duì)象必須是函數(shù),存儲(chǔ)過(guò)程,視圖或觸發(fā)器。',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'對(duì)象沒(méi)有加密!'
--SQL Server 2012
--throw 50001, N'無(wú)效的對(duì)象!要解密的對(duì)象必須是函數(shù),存儲(chǔ)過(guò)程,視圖或觸發(fā)器。',1
return
end
declare @sql nvarchar(max) --解密出來(lái)的SQL語(yǔ)句
,@imageval nvarchar(max) --加密字符串
,@tmpStr nvarchar(max) --臨時(shí)SQL語(yǔ)句
,@tmpStr_imageval nvarchar(max) --臨時(shí)SQL語(yǔ)句(加密后)
,@type char(2) --對(duì)象類型('P','V','TR','FN','IF','TF')
,@objectID int --對(duì)象ID
,@i int --While循環(huán)使用
,@Oject1 nvarchar(1000)
set @objectID=object_id(@Object)
set @type=(select a.type from sys.objects a where a.object_id=@objectID)
declare @Space4000 nchar(4000)
set @Space4000=replicate('-',4000)
/*
@tmpStr 會(huì)構(gòu)造下面的SQL語(yǔ)句
-------------------------------------------------------------------------------
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 '+@Oject1+' with encryption as select 1 as column1 '
when @type ='V ' then N'Alter View '+@Oject1+' with encryption as select 1 as column1 '
when @type ='FN' then N'Alter Function '+@Oject1+'() returns int with encryption as begin return(0) end '
when @type ='IF' then N'Alter Function '+@Oject1+'() returns table with encryption as return(Select a.name from sys.types a) '
when @type ='TF' then N'Alter Function '+@Oject1+'() returns @t table(name nvarchar(50)) with encryption as begin return end '
else 'Alter Trigger '+@Oject1+'on '+quotename(object_schema_name(@objectID))+'.'+(select Top(1) quotename(object_name(parent_id)) from sys.triggers a where a.object_id=@objectID)+' with encryption for update as return '
end
set @tmpStr=@tmpStr+'/*'+@Space4000
set @i=0
while @i < (ceiling(@MaxLength*1.0/4000)-1)
begin
set @tmpStr=@tmpStr+ @Space4000
Set @i=@i+1
end
set @tmpStr=@tmpStr+'*/'
------------
set @imageval =(select top(1) a.imageval from sys.sysobjvalues a where a.objid=@objectID and a.valclass=1)
begin tran
exec(@tmpStr)
set @tmpStr_imageval =(select top(1) a.imageval from sys.sysobjvalues a where a.objid=@objectID 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 @sql=@sql+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' --標(biāo)識(shí)為系統(tǒng)對(duì)象
go


如果SQL Server 2012,請(qǐng)修改下面兩個(gè)位置的代碼。方法類似于前面的加密過(guò)程:
SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析
搭建測(cè)試環(huán)境
--------------------------------------------------------------------------------
在一個(gè)測(cè)試環(huán)境中(DB: Test),先執(zhí)行上面的加密存儲(chǔ)過(guò)程(sp_EncryptObject)和解密存儲(chǔ)過(guò)程(sp_EncryptObject);再創(chuàng)建兩個(gè)表:TableA & TableB

復(fù)制代碼 代碼如下:


use test
go
--創(chuàng)建表: 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


接下來(lái),我們要?jiǎng)?chuàng)建6個(gè)未加密的對(duì)象(對(duì)象類型包含 'P','V','TR','FN','IF','TF'):
1.視圖(myView):

復(fù)制代碼 代碼如下:


if object_id('myView') is not null drop view myView
go
create view myView
As
select * from TableA;
go


2.觸發(fā)器(MyTrigger):

復(fù)制代碼 代碼如下:


if object_id('MyTrigger') is not null drop Trigger MyTrigger
go
create trigger MyTrigger
on TableA
for update
As
insert into TableB(ID,data) select a.ID,a.Data From Inserted a
go


3.存儲(chǔ)過(guò)程(MyProc):

復(fù)制代碼 代碼如下:


if object_id('MyProc') is not null drop proc MyProc
go
create proc MyProc
(
@data nvarchar(50)
)
As
insert into TableA(data) values(@data)
go


4.用戶定義表值函數(shù)(TF)(MyFunction_TF):

復(fù)制代碼 代碼如下:


if object_id('MyFunction_TF') is not null drop function MyFunction_TF
go
create function MyFunction_TF
(
)
returns @t table
(
id int,
data nvarchar(50)
)
As
begin
insert @t(id,data) select id,data from TableA
return
end
go


5.內(nèi)聯(lián)表值函數(shù)(IF) (MyFunction_IF):

復(fù)制代碼 代碼如下:


if object_id('MyFunction_IF') is not null drop function MyFunction_IF
go
create function MyFunction_IF
(
)
returns table
As
return(select top(3) id, data from TableA order by id desc)
go


6.標(biāo)量函數(shù)(FN)(MyFunction_FN):

復(fù)制代碼 代碼如下:


if object_id('MyFunction_FN') is not null drop function MyFunction_FN
go
create function MyFunction_FN
(
)
returns nvarchar(50)
As
begin
return(select top(1) data from TableA order by id desc)
end
go


當(dāng)執(zhí)行完了上面的1-6步驟的腳本,我們通過(guò)查詢系統(tǒng)視圖sys.sql_modules,可以看到未加密前的定義信息:

復(fù)制代碼 代碼如下:


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


SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析 
加密測(cè)試
--------------------------------------------------------------------------------
下面我就通過(guò)調(diào)用加密存儲(chǔ)過(guò)程(sp_EncryptObject),一次性對(duì)它們進(jìn)行加密:

復(fù)制代碼 代碼如下:


use test
go
exec sp_EncryptObject 'all'
go


SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析

當(dāng)我們?cè)俨榛叵到y(tǒng)視圖sys.sql_modules,會(huì)發(fā)現(xiàn)definition列返回的是null值,說(shuō)明定義內(nèi)容已經(jīng)給加密:

SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析


解密測(cè)試
--------------------------------------------------------------------------------
解密過(guò)程,必須在DAC連接SQL Server,我們這里例子是從 SSMS(SQL Server Management Studio) 查詢編輯器啟動(dòng) DAC,如圖:
admin:to the instance name in the format sqlcmd -Sadmin:<instance_name>. You can also initiate a DAC from a Query Editor by connecting to admin:<instance_name>.'>SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析 
解密存儲(chǔ)過(guò)程(sp_DecryptObject),只能一次對(duì)一個(gè)存儲(chǔ)過(guò)程、函數(shù)、視圖或觸發(fā)器,進(jìn)行解密:

復(fù)制代碼 代碼如下:


use test
go
exec sp_DecryptObject MyTrigger
go


SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析 
當(dāng)定義內(nèi)容長(zhǎng)度超過(guò)4000,我們可以指定@MaxLength的值,如:

復(fù)制代碼 代碼如下:


exec sp_DecryptObject fn_My,20000
go


這里(fn_My)是一個(gè)函數(shù),定義內(nèi)容超過(guò)了8000: 

SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析

... ...

SQL Server存儲(chǔ)過(guò)程加密和解密原理深入分析

 
小結(jié)
--------------------------------------------------------------------------------
雖然,上面的腳本,我已經(jīng)在SQL Server 2008 R2 和SQL Server 2012測(cè)試過(guò),但無(wú)法避免一些未知錯(cuò)誤 。如果你自己在測(cè)試上面的腳本,請(qǐng)不要在生產(chǎn)環(huán)境上。如果你在應(yīng)用過(guò)程,碰到有什么問(wèn)題或有什么意見(jiàn)和建議可以發(fā)email聯(lián)系我或跟帖,在此非常感謝!

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 91丨九色丨国产 | 欧美久久久久久久 | 国产精品国产自产拍高清av | 国产精品欧美一区二区 | 欧美在线网站 | 国产精品videosex极品 | 免费成人在线视频网站 | 亚洲免费视频大全 | ts人妖另类精品视频系列 | 午夜精品福利在线观看 | 国产精品福利电影网 | 蜜桃国精产品二三三区视频 | 国产中文| 国产精品毛片a√一区 | 精品国产一级 | 久久影院免费观看 | 久久国产一区 | 久久精品国产免费 | 婷婷综合久久 | 亚洲成av人片在线观看无码 | 99激情| 日韩一区中文字幕 | 亚洲精品成人免费 | 日韩欧美一级电影 | 久久99这里只有精品 | 国产综合精品一区二区三区 | 综合网av | 成人福利网站 | 日韩激情免费视频 | 午夜激情在线免费观看 | 日韩综合一区 | 激情国产精品 | 精品视频一区二区三区四区 | 成人福利视频 | 午夜播放器在线观看 | 亚洲 在线 | 欧美在线操 | 精品伊人久久 | 亚洲第一成年人视频 | 亚洲欧美成人综合 | 自拍偷拍第一页 |