• 在SQL SERVER中实现RSA加密算法


     

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

    需要特别注意:如果要对中文进行加密,那么所选取的两个素数要比较大,两个素数的成绩最好要大于65536,即大于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=)

         begin

            set @flg=0

           break

         end 

         set @i=@i+1

     end

     return @flg

    end

    go

    --判断两个数是否互素

     

    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值,然后进行加密,产生3个字节的16位数据*/

     

    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

    【测试】

    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

  • 相关阅读:
    JSON的序列化与还原
    正则表达式的一些基础
    跨域二三事
    与Web服务器通信
    与 Web 服务器通信
    代码重构
    构造函数与各种继承方法特点
    this指向问题——严格、非严格模式,事件处理程序
    《JavaScript设计模式与开发实践》学习笔记——单例模式
    Git常用命名及常见操作流程
  • 原文地址:https://www.cnblogs.com/trieagle/p/1639927.html
Copyright © 2020-2023  润新知