• 对存储过程进行加密和解密(SQL 2008/SQL 2012)


    用于加密的存储过程 (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):


    View Code

     如果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:

    ... ...

  • 相关阅读:
    js 基础(面试前必看)
    typescript 使用的几种情况
    flutter 命令卡主的问题
    React 通过注释自动生成文档
    jest 测试入门(一)
    react hooks 全面转换攻略(三) 全局存储解决方案
    缓存穿透、击穿、雪崩区别和解决方案
    java8 lambda表达式
    maven中snapshot快照库和release发布库的区别和作用
    初识 Nacos 以及安装
  • 原文地址:https://www.cnblogs.com/zzw1986/p/4664326.html
Copyright © 2020-2023  润新知