非对称加密与RSA算法
文章目录
公开密码体系的产生原因
1.对称密码体系中密钥的传递存在风险,虽然信息是加密传送的,但是密钥是明文传送的(即使密钥是加密传送的,密钥的密钥也是明文传递的).一旦密钥被截获则加密失效
2.希望使用一种加密和解密不同密钥的密码体系,公钥可以明文传递,但是私钥由接收方私自持有.公钥加密只能私钥解密,私钥加密只能公钥解密
RSA加密算法
抛开原理不谈,这个非对称加密听起来挺玄学的
算法流程
1.Bob选择两个大素数p,q
2.Bob计算 n = p q , z = ( p − 1 ) ( q − 1 ) n=pq,z=(p-1)(q-1) n=pq,z=(p−1)(q−1)
3.Bob选择一个 e < n , g c d ( e , z ) = 1 e<n,gcd(e,z)=1 e<n,gcd(e,z)=1
4.Bob求 e e e在模z意义下的乘法逆元 d d d,即求一个d,使得 e d m o d z = 1 ed\ mod \ z=1 ed mod z=1
5.Bob对外公布他的公钥 K B o b + ( n , e ) K^+_{Bob}(n,e) KBob+(n,e),Bob自己持有私钥 K B o b − ( n , d ) K^-_{Bob}(n,d) KBob−(n,d)
6.Alice根据Bob的公钥
K
B
o
b
+
(
n
,
e
)
K^+_{Bob}(n,e)
KBob+(n,e)加密她要问候Bob的话
m
m
m(m是一个十进制整数并且小于n),方法是
c
=
m
e
m
o
d
n
c=m^e \ mod \ n
c=me mod n
其中c是加密后的密文,然后Alice发送密文
7.Bob在收到加密的信息c后,Bob使用自己的私钥
K
B
o
b
−
(
n
,
d
)
K^-_{Bob}(n,d)
KBob−(n,d)解密,方法是
m
=
c
d
m
o
d
n
m=c^d\ mod\ n
m=cd mod n
其中m是解密后的明文
举例说明
在线的RSA计算器RSA Calculator (drexel.edu)
1.Bob选择"大"素数 p = 17 , q = 19 p=17,q=19 p=17,q=19
2.Bob计算 n = p q = 323 , z = ( p − 1 ) ( q − 1 ) = 288 n=pq=323,z=(p-1)(q-1)=288 n=pq=323,z=(p−1)(q−1)=288
3.Bob选择一个 e = 37 < n = 323 , g c d ( 37 , 288 ) = 1 e=37<n=323,gcd(37,288)=1 e=37<n=323,gcd(37,288)=1
4.Bob求 e = 37 e=37 e=37在mod 288 288 288下的乘法逆 d = 109 d=109 d=109
需要用到拓展欧几里得算法
5.Bob对外公布公钥 K B o b + ( n = 323 , e = 37 ) K^+_{Bob}(n=323,e=37) KBob+(n=323,e=37),自己持有私钥 K − B o b ( n = 323 , d = 109 ) K^-{Bob}(n=323,d=109) K−Bob(n=323,d=109)
6.Alice拿到Bob的公钥
K
B
o
b
+
(
n
=
323
,
e
=
37
)
K^+_{Bob}(n=323,e=37)
KBob+(n=323,e=37),想要加密
88
88
88
c
=
m
e
m
o
d
n
=
8
8
37
m
o
d
323
=
107
c=m^e \ mod \ n=88^{37} \ mod 323=107
c=me mod n=8837 mod323=107
需要用到快速幂算法
7.Bob拿到Alice发来的密文之后,使用私钥
K
−
B
o
b
(
n
=
323
,
d
=
109
)
K^-{Bob}(n=323,d=109)
K−Bob(n=323,d=109)解密
m
=
c
d
m
o
d
n
=
10
7
109
m
o
d
323
=
109
m=c^d\ mod\ n=107^{109} \ mod \ 323=109
m=cd mod n=107109 mod 323=109
需要用到快速幂算法
计算方法
拓展欧几里得算法求乘法逆元
已知 g c d ( e , z ) = 1 , e d ≡ 1 ( m o d z ) gcd(e,z)=1,ed\equiv1(mod\ z) gcd(e,z)=1,ed≡1(mod z),求d
由
e
d
≡
1
(
m
o
d
z
)
ed\equiv1(mod\ z)
ed≡1(mod z)可以得到
e
d
=
k
z
+
1
⇒
e
d
−
k
z
=
1
ed=kz+1\Rightarrow ed-kz=1
ed=kz+1⇒ed−kz=1由于k是一个任意整数,带不带符号无所谓于是有
e
d
+
k
z
=
1
=
g
c
d
(
e
,
z
)
ed+kz=1=gcd(e,z)
ed+kz=1=gcd(e,z)
拓展欧几里得定理:
a
x
+
b
y
=
g
c
d
(
a
,
b
)
g
c
d
(
a
,
b
)
=
g
c
d
(
b
,
a
%
b
)
b
x
1
+
a
%
b
y
1
=
g
c
d
(
b
,
a
%
b
)
ax+by=gcd(a,b)\\ gcd(a,b)=gcd(b,a\%b)\\ bx_1+a\%by_1=gcd(b,a\%b)\\
ax+by=gcd(a,b)gcd(a,b)=gcd(b,a%b)bx1+a%by1=gcd(b,a%b)
得到 a x + b y = b x 1 + a % b y 1 = b x 1 + ( a − ⌊ a b ⌋ × b ) y 1 = a y 1 + b ( x 1 − ⌊ a b ⌋ y 1 ) ax+by=bx_1+a\%by_1=bx_1+(a-\lfloor\frac{a}{b}\rfloor\times b)y_1=ay_1+b(x_1-\lfloor\frac{a}{b}\rfloor y_1) ax+by=bx1+a%by1=bx1+(a−⌊ba⌋×b)y1=ay1+b(x1−⌊ba⌋y1)
令等号两侧a和b的系数分别相等有
{
x
=
y
1
y
=
x
1
−
⌊
a
b
⌋
y
1
\begin{cases} x=y_1\\ y=x_1-\lfloor\frac{a}{b}\rfloor y_1 \end{cases}
{x=y1y=x1−⌊ba⌋y1
这时候我们大体可以写出递归函数的形式了,但是还有一个函数出口的问题,什么时候停止递归呢
g c d ( a , b ) gcd(a,b) gcd(a,b)算法会在b=0时返回a作为最大公约数,拓展欧几里得算法也是如此
停止递归时x,y分别设置为多少呢?
算法停止时有 g c d ( a n , 0 ) = a n x + 0 y gcd(a_n,0)=a_nx+0y gcd(an,0)=anx+0y
又 g c d ( a n , 0 ) = a n gcd(a_n,0)=a_n gcd(an,0)=an
于是令 x = 1 , y = 0 x=1,y=0 x=1,y=0
int exgcd(const int &a,const int &b,int &x,int &y){
if(b==0){
x=1;
y=0;
return a;
}
int x1,y1;
int d=exgcd(b,a%b,x1,y1);
x=y1;
y=x1-a/b*y1;
return d;
}
快速幂+费马小定理求乘法逆元
费马小定理
当p是素数,a是任意整数,有
a
p
≡
a
(
m
o
d
p
)
a^p\equiv a(mod\ p)
ap≡a(mod p)
费马小定理的数学归纳法证明:
当 a > p a>p a>p时通过取模可以使结果落在 [ 0 , p − 1 ] [0,p-1] [0,p−1]范围内,因此只需要证明该范围内a成立
假设结论对 a a a成立,即有 a p ≡ a ( m o d p ) a^p\equiv a(mod\ p) ap≡a(mod p)
则 ( a + 1 ) p (a+1)^p (a+1)p二项展开有 ( a + 1 ) p = a p + C p p − 1 a p − 1 + C p p − 2 a p − 2 + . . . + 1 (a+1)^p=a^p+C_p^{p-1}a^{p-1}+C_{p}^{p-2}a^{p-2}+...+1 (a+1)p=ap+Cpp−1ap−1+Cpp−2ap−2+...+1
又当 i ∈ [ 1 , p − 1 ] , p ∣ C p i i\in[1,p-1],p|C_{p}^i i∈[1,p−1],p∣Cpi
C p i = p ! i ! ( n − i ) ! = p × ( p − 1 ) ! i ! ( n − i ) ! C_{p}^i=\frac{p!}{i!(n-i)!}=p\times\frac{(p-1)!}{i!(n-i)!} Cpi=i!(n−i)!p!=p×i!(n−i)!(p−1)!
因此 ( a + 1 ) p ≡ a p + 1 ( m o d p ) (a+1)^p\equiv a^p+1(mod\ p) (a+1)p≡ap+1(mod p)
由归纳假设 a p ≡ a ( m o d p ) a^p\equiv a(mod\ p) ap≡a(mod p)带入上式有
( a + 1 ) p ≡ a + 1 ( m o d p ) (a+1)^p\equiv a+1(mod\ p) (a+1)p≡a+1(mod p)
因此结论对a+1时也成立
注意逆定理不成立,有"伪素数"这个东西
求乘法逆元:已知 g c d ( e , z ) = 1 , e d ≡ 1 ( m o d z ) gcd(e,z)=1,ed\equiv1(mod\ z) gcd(e,z)=1,ed≡1(mod z),求d
由 g c d ( e , z ) = 1 gcd(e,z)=1 gcd(e,z)=1得到 e z ≡ e ( m o d z ) e^z\equiv e(mod\ z) ez≡e(mod z)
又 e d ≡ 1 ( m o d z ) ed\equiv1(mod\ z) ed≡1(mod z)等号两侧同时乘以 e 2 e^2 e2得到 e 2 d ≡ e ( m o d z ) ≡ e z ( m o d z ) e^2d\equiv e(mod\ z)\equiv e^z(mod \ z) e2d≡e(mod z)≡ez(mod z)
于是 d ≡ e z − 2 ( m o d z ) d\equiv e^{z-2}(mod \ z) d≡ez−2(mod z)
下面就可以用快速幂计算d了
快速幂求 m e m o d n m^e\ mod\ n me mod n
快速幂算法
计算
x
n
x^n
xn时
x
n
=
{
1
,
n
=
0
x
,
n
=
1
(
x
2
)
n
2
,
n
为
偶
数
(
x
2
)
n
−
1
2
×
x
,
n
为
奇
数
x^n=\begin{cases} 1,n=0\\ x,n=1\\ (x^2)^{\frac{n}{2}},n为偶数\\ (x^2)^\frac{n-1}{2}\times x,n为奇数 \end{cases}
xn=⎩⎪⎪⎪⎨⎪⎪⎪⎧1,n=0x,n=1(x2)2n,n为偶数(x2)2n−1×x,n为奇数
又由于乘法对于取模很随意
[
(
a
m
o
d
n
)
⋅
(
b
m
o
d
n
)
]
m
o
d
n
=
(
a
⋅
b
)
m
o
d
n
[(a \ mod \ n)·(b\ mod\ n)]mod \ n=(a·b)mod \ n
[(a mod n)⋅(b mod n)]mod n=(a⋅b)mod n
因此
x
n
m
o
d
m
=
{
1
,
n
=
0
x
m
o
d
m
,
n
=
1
(
x
2
m
o
d
m
)
n
2
m
o
d
m
,
n
为
偶
数
(
x
2
m
o
d
m
)
n
−
1
2
×
x
m
o
d
m
,
n
为
奇
数
x^n \ mod \ m=\begin{cases} 1,n=0\\ x\ mod \ m,n=1\\ (x^2\ mod \ m)^{\frac{n}{2}}\ mod \ m,n为偶数\\ (x^2\ mod \ m)^\frac{n-1}{2}\times x\ mod \ m,n为奇数 \end{cases}
xn mod m=⎩⎪⎪⎪⎨⎪⎪⎪⎧1,n=0x mod m,n=1(x2 mod m)2n mod m,n为偶数(x2 mod m)2n−1×x mod m,n为奇数
int quick_pow(const int &base, const int &index, const int &p) {
if (index == 0)
return 1;
else if (index == 1)
return base % p;
else if (index % 2) {
int temp = base * base % p;
return quick_pow(temp, index >> 1, p) * base % p;
} else {
int temp = base * base % p;
return quick_pow(temp, index >> 1, p);
}
}