程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> SqlServer數據庫 >> 關於SqlServer >> 在SQL SERVER中實現RSA加密算法

在SQL SERVER中實現RSA加密算法

編輯:關於SqlServer


  /*本次修改增加了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=0 )
     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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved