使用RSA演算法在解密的計算時會需要較多時間,這時可以利用中國剩餘定理來加速
假設現在有一組金鑰,是由質數p,q生成,其中公鑰(e,n),私鑰(d,n),n=pq
在生成RSA金鑰的步驟中,最後一步是把p,q銷毀,但是在擁有私鑰的這一方若保留這兩個數則可以加快運算時間
假設收到一筆加密資料C
原本要計算的是
m=Cdmodn=Cdmod(pq)
把它轉換成中國剩餘定理的題型
{x≡m1(modp)x≡m2(modq)
m1=Cdmodpm2=Cdmodq
x的最小正整數解就是Cd
解這個方程式,令x=m2+kq,帶入第一式
m2+kq≡m1(modp)
m1−m2≡kq(modp)
因為p,q為質數,gcd(p,q)=1
所以q存在模反原素 q−1,qq−1≡1(modp)
q−1(m1−m2)≡k(modp)
k的最小正整數解為 q−1(m1−m2)modp
⇒x=m2+q(q−1(m1−m2)modp)
再來說明為什麼比較快
m1=Cdmodp
p是質數⇒Cp−1≡1(modp)
所以求 m1 時只要計算C(dmod(p−1))modp 即可
同理 m2=C(dmod(q−1))modq
重新整理一下式子並給予一些定義
dp=dmod(p−1)
dq=dmod(q−1)
qinv=q−1modp
這三個值是產生key時可以先算出來的
接下來要解密時只要以下步驟
m1=Cdpmodp
m2=Cdqmodq
h=qinv(m1−m2)modp,這個餘數要找最小正整數
m=m2+hq
接下來使用openssl產生一組key來玩玩看
預設public key為65537,據說加密計算比較快,還沒研究到這邊
接下來看一下key的內容
參數對應
modulus: n
publicExponent: e
privateExponent: d
prime1: p
prime2: q
exponent1: dp
exponent2: dq
coefficient: qinv
在拿key來加解密前,先練習一下用p,q算出其他參數
load bigint set p [bigint::convert 0x00fda39a0d5a044b0eb0eb9773afa747ed2f16cb609a049a50d0d6436f90f0df5f3f7f3fe9862ad71fd917d56451c219248812ddc943f413c27264e2806447a4cf] set q [bigint::convert 0x00dfa9e58cb45e31f4013c8166b5b61eb94cde61b03f16e5a337300b6824c3531522239563cdf6af73b44e32f820b8edd3165de662c980e0b4025620e5bca09bb1] set e 65537 set phy_n [bigint::mul [bigint::sub $p 1] [bigint::sub $q 1]] set n [bigint::mul $p $q] set d [bigint::invert 65537 $phy_n] set dp [bigint::mod $d [bigint::sub $p 1]] set dq [bigint::mod $d [bigint::sub $q 1]] set qinv [bigint::invert $q $p] foreach item {n d dp dq qinv} { puts $item=[bigint::hex [set $item]] }
再來就加密後用不同方法解密比一下時間
# 先產生10000組數據 for {set i [bigint::convert 0]} {[bigint::cmp 10000 $i]} {set i [bigint::add $i 1]} { set C($i) [bigint::powm $i $e $n] # set m [bigint::powm $c $d $n] # puts "i=$i\tc=$c\tm=$m" } # 用同樣的數據做2次解密比較時間 puts [time { for {set i [bigint::convert 0]} {[bigint::cmp 10000 $i]} {set i [bigint::add $i 1]} { bigint::powm $C($i) $d $n } }] puts [time { for {set i [bigint::convert 0]} {[bigint::cmp 10000 $i]} {set i [bigint::add $i 1]} { set m1 [bigint::powm $C($i) $dp $p] set m2 [bigint::powm $C($i) $dq $q] set h [bigint::mod [bigint::mul $qinv [bigint::sub $m2 $m1]] $p] set m [bigint::add $m2 [bigint::mul $h $q]] } }]
win7 64bit i5-3230M
32950712 microseconds per iteration
10468731 microseconds per iteration
RaspberryPi
302722638 microseconds per iteration
98416506 microseconds per iteration
RSA的計算很花時間,所以通常應用時只用來初始化,先用RSA的方式溝通取得共用金鑰之後再用比較快的演算法加密
沒有留言:
張貼留言