在SQL SERVER中实现RSA加密算法

王朝学院·作者佚名  2010-01-07
窄屏简体版  字體: |||超大  

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

(请您对文章做出评价)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航