【叶子函数分享五十二】在SQL SERVER中实现RSA加解密函数(第二版)

/***************************************************  

    作者:herowang(让你望见影子的墙)

    日期:2010.1.5

    注: 转载请保留此信息

    更多内容,请访问我的博客:blog.csdn.net/herowang

****************************************************/

/*

   本次修改增加了unicode的支持,但是加密后依然显示为进制数据,因为进行RSA加密后所得到的unicode编码是无法显示的,所以密文依然采用进制数据显示。

   需要特别注意:如果要对中文进行加密,那么所选取的两个素数要比较大,两个素数的成绩最好要大于,即大于unicode的最大编码值

   另外修改了第一个版本的部分函数名称

*/

 

SQL SERVER中实现RSA加密算法

--判断是否为素数

if object_id('f_primeNumTest') is not null

  drop function f_primeNumTest

go

create function [dbo].[f_primeNumTest]

(@p int)

returns bit

begin

  declare @flg bit,@i int

  select @flg=1, @i=2

  while @i<=sqrt(@p)

  begin

     if(@p%@i=0  )

     begin

        set @flg=0

       break

     end 

     set @i=@i+1

  end

  return @flg

end

go

--测试示例:

select [dbo].[f_primeNumTest](23)--1

select [dbo].[f_primeNumTest](24)--0

select [dbo].[f_primeNumTest](25)--0

select [dbo].[f_primeNumTest](26)--0

select [dbo].[f_primeNumTest](27)--0

 

--判断两个数是否互素

if object_id('f_isNumsPrime') is not null

  drop function f_isNumsPrime

go

create function f_isNumsPrime

(@num1 int,@num2 int)

returns bit

begin

  declare @tmp int,@flg bit

  set @flg=1

  while (@num2%@num1<>0)

  begin

    select @tmp=@num1,@num1=@num2%@num1,@num2=@tmp

  end

  if @num1=1

     set @flg=0

  return @flg

end

 

go

--产生密钥对

if object_id('p_createKey') is not null

  drop proc p_createKey

go

create proc p_createKey

@p int,@q int

as

begin

    declare @n bigint,@t bigint,@flag int,@d int

    if dbo.f_primeNumTest(@p)=0

    begin

       print cast(@p as varchar)+'不是素数,请重新选择数据'

       return

    end

    if dbo.f_primeNumTest(@q)=0

    begin

       print cast(@q as varchar)+'不是素数,请重新选择数据'

       return

  end

  print '请从下列数据中选择其中一对,作为密钥'

    select @n=@p*@q,@t=(@p-1)*(@q-1)

    declare @e int

    set @e=2

    while @e<@t

    begin

       if dbo.f_isNumsPrime(@e,@t)=0

       begin

          set @d=2

       while @d<@n

            begin

              if(@e*@d%@t=1)

                 print cast(@e as varchar)+space(5)+cast(@d as varchar)

              set @d=@d+1

            end

    end

       set @e=@e+1       

    end

end

 

/*加密函数说明,@key 为上一个存储过程中选择的密码中的一个,@p ,@q 产生密钥对时选择的两个数。获取每一个字符的unicode值,然后进行加密,产生个字节的位数据*/

if object_id('f_RSAEncry') is not null

  drop function f_RSAEncry

go

create function f_RSAEncry

 (@s varchar(100),@key int ,@p int ,@q int)

returns nvarchar(4000)

as

begin

   declare @crypt varchar(8000)

     set @crypt=''

   while len(@s)>0

   begin

              declare @i bigint,@tmp varchar(10),@k2 int,@leftchar int

              select @leftchar=unicode(left(@s,1)),@k2=@key/2,@i=1

              while @k2>0

              begin

                     set @i=(cast(power(@leftchar,2) as bigint)*@i)%(@p*@q)

                     set @k2=@k2-1

              end 

              set @i=(@leftchar*@i)%(@p*@q)   

              set @tmp=''

              select @tmp=case when @i%16 between 10 and 15 then char( @i%16+55) else cast(@i%16 as varchar) end +@tmp,@i=@i/16

              from (select number from master.dbo.spt_values where type='p'  and number<10 )K

              order by  number desc

              set @crypt=@crypt+right(@tmp,6)

              set @s=stuff(@s,1,1,'')

  end

  return @crypt

end

 

--解密:@key 为一个存储过程中选择的密码对中另一个数字,@p ,@q 产生密钥对时选择的两个数

if object_id('f_RSADecry') is not null

  drop function f_RSADecry

go

create function f_RSADecry

 (@s nvarchar(4000),@key int ,@p int ,@q int)

returns nvarchar(4000)

as

begin

  declare @crypt varchar(8000)

  set @crypt=''

  while len(@s)>0

    begin

       declare @leftchar bigint

       select @leftchar=sum(data1)

       from (select case upper(substring(left(@s,6), number, 1)) when 'A' then 10

                                                    when 'B' then 11

                                                    when 'C' then 12

                                                    when 'D' then 13

                                                    when 'E' then 14

                                                    when 'F' then 15

                else substring(left(@s,6), number, 1)

                end* power(16, len(left(@s,6)) - number) data1

         from (select number from master.dbo.spt_values where type='p')K

         where number <= len(left(@s,6))

     ) L

    declare @k2 int,@j bigint

       select @k2=@key/2,@j=1

    while @k2>0

       begin

      set @j=(cast(power(@leftchar,2)as bigint)*@j)%(@p*@q)

      set @k2=@k2-1

    end

    set @j=(@leftchar*@j)%(@p*@q)

    set @crypt=@crypt+nchar(@j)

    set @s=stuff(@s,1,6,'')

    end

  return @crypt

end

 

使用方法:

1、先使用p_createkey生成一对密钥,参数为两个参数

2、调用相应进行加密、解密

--【测试】

if object_id('tb') is not null

   drop table tb

go

create table tb(id int identity(1,1),col varchar(100))

go

insert into tb values(dbo.f_RSAEncry('中国人',779,1163,59))

insert into tb values(dbo.f_RSAEncry('Chinese',779,1163,59))

select * from tb

 

--运行结果

/*

id          col

----------- ---------------------------------------------

1           00359B00E6E000EAF5

2           01075300931B0010A4007EDC004B340074A6004B34

*/

 

select * ,解密后=dbo.f_RSADecry(col,35039,1163,59)from tb

 

--测试示例

/*

id          col                                         解密后   

----------- ------------------------------------------- -----------

1           00359B00E6E000EAF5                          中国人

2           01075300931B0010A4007EDC004B340074A6004B34  Chinese

*/

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值