zl程序教程

您现在的位置是:首页 >  其他

当前栏目

RSA算法原理及其在HTTPS中的应用

2023-03-15 22:01:18 时间

本文在阅读不少他人的优秀博文以及查阅HTTPS协议和RSA等相关资料的基础上整理而成,包含了RSA算法的详细原理及其在HTTPS中的应用。RSA作为HTTPS协议中最为核心的加密/解密算法,其原理却很简单,很容易理解。当你读完本文之后,你也会惊叹于RSA算法发明者的奇思妙想。

首先,RSA的密钥越长,就越难破解。目前被破解的最长RSA密钥是768位二进制。也就是说,长度超过768位的密钥,还无法破解(至少没有人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥及其安全。下面就让我们来认识RSA算法。

##一、互质关系 如果两个正整数,除了1以外,没有其他公因子,我们就称这两个数是互质关系(coprime)。比如,15和32没有公因子,所以它们是互质关系。这说明,不是质数也可以构成互质关系。关于互质关系,有如下结论:

  • 1、任意两个质数构成互质关系,如13和61;
  • 2、一个数是质数,另一个数只要不是前者的倍数,则两者构成互质关系;
  • 3、如果两个数之中,较大的那个数是质数,则两者构成互质关系,如97和57;
  • 4、1和任意一个自然数都是互质关系,比如1和99;
  • 5、p是大于1的整数,则p和p-1构成互质关系,如57和56;
  • 6、p是大于1的奇数,则p和p-2构成互质关系,如17和15。 ##二、中国余数定理 原本RSA算法和中国余数定理没有什么直接的联系,但即将介绍的欧拉函数的证明需要用到中国余数定理,固在这里先行介绍一下。 中国余数定理:给出
m

个两两互质的整数,且它们的乘积为

P

。假设有一个未知数

M

,如果我们已知

M

分别除以这

m

个数所得的余数,那么在0到

P-1

的范围内,我们可以唯一地确定这个

M

。这个值可以看作是

M

的一个特解。其它所有满足条件的

M

,则正好是那些除以

P

之后余数等于这个特解的数。

从某种角度来说,中国余数定理几乎是显然的。让我们以两个比较小且互质的整数3和4来理解中国余数定理背后的直觉。其中

x mod y

表示

x

除以

y

的余数。

从表中可以看到,

i mod 3

的值以3位周期在循环,而

imod 4

则以4为周期在循环。由于3和4是互质的,它们的最小公倍数为12,因而

(imod 3,space imod 4)

的循环周期是12,不会更短。因此,当

i

从0增加到11时,

(imod 3,space imod 4)

的值始终没有重复出现。同时,

(imod 3,space imod 4)

也只有12种不同的取值,即当

i

从0增加到11时,

(imod 3,space imod 4)

i

之间存在一一映射。这就是中国余数定理的内容。

##三、欧拉函数 请思考以下问题:任意给定正整数

n

,请问在小于等于

n

的正整数中,有多少个与

n

构成互质关系?

计算这个值的方法就叫做欧拉函数,以

varphi(n)

表示。在1~8中,与8形成互质关系的是1,3,5,7,所以

varphi(8)=4

varphi(n)

的计算方法并不复杂,但为了得到最后的公式,我们需要分以下五种情形讨论:

  • 第一种情况:
n=1

,则

varphi(1)

=1,因为1与任何数(包括自身)构成互质关系。

  • 第二种情况:
n

是质数,则

varphi(n)=n-1

。因质数与小于它的每一个数都构成互质关系。

  • 第三种情况 如果
n

是质数的某个次方,即

n=p^k

p

为质数,

k

为大于等于1的整数),则

varphi(p^k)=p^k-p^{k-1}

。这是因为只有当一个数的因子不包含质数

p

,才能与

n

互质。而因子包含质数

p

的数一共有

p^{k-1}

个(

1 imes p,2 imes p,ldots,p^{k-1} imes p

),把它们去除,剩下的就是与

n

互质的数。 上面的式子还可以写成

varphi(p^k)=p^k(1-frac{1}{p})

。可以看出,第二种情况是第三种情况中

k=1

的特例。

  • 第四种情况 如果
n

可以分解成两个互质的整数之积,即

n=p_1cdot p_2

,则

varphi(n)=varphi(p_1 cdot p_2)=varphi(p_1)cdotvarphi(p_2)

,比如

varphi(56)=varphi(8 imes7)=varphi(8)cdotvarphi(7)=4 imes6=24

。 其实这条结论用“中国余数定理“就很好理解了。简单说下思路:如果

a

p_1

互质(

a<p_1

),

b

p_2

互质(

b<p_2

),

c

p_1p_2

互质(

c<p_1p_2

),则

c

与数对

(a,b)

是一一对应关系。由于

a

varphi(p_1)

种可能,

b

的值有

varphi(p_2)

种可能,则数对

(a,b)

varphi(p_1)varphi(p_2)

种可能。而

c

的值有

varphi(p_1)varphi(p_2)

种可能,所以

varphi(n)=varphi(p_1 cdot p_2)=varphi(p_1)cdotvarphi(p_2)

。 补充说明:我们还可以证明一种更加特殊的情况:如果

n

可以分解为两个质数之积,即

n=p_1 imes p_2

p_1

p_2

为质数),那么

varphi(n)=varphi(p_1 cdot p_2)=varphi(p_1)cdotvarphi(p_2)

。证明这如下: 证明:

ecause p_1

p_2

为质数,

herefore

p_1cdot p_2

不互质的数必然包含

p_1

p_2

。 包含

p_1

p_2

的数有:

1 imes p_1,2 imes p_1,ldots,p_2cdot p_1,1 imes p_2,2 imes p_2,ldots,p_1cdot p_2

。 由第二种情况知,

varphi(p_1)=p_1-1

varphi(p_2)=p_2-1

,即

varphi(n)=varphi(p_1 cdot p_2)=varphi(p_1)cdotvarphi(p_2)

。 证毕。

  • 第五种情况 因为任意一个大于1的正整数,都可以写成一系列质数的积:
n=p_1^{k_1}p_2^{k_2}ldots p_r^{k_r}

,根据第四种情况,有

varphi(n)=varphi(p_1^{k_1})varphi(p_2^{k_2})ldotsvarphi(p_r^{k_r})

,再根据情况三,有:

varphi(n)=p_1^{k_1}p_2^{k_2}ldots p_r^{k_r}(1-frac{1}{p_1})(1-frac{1}{p_2})ldots(1-frac{1}{p_r})

,这就是欧拉函数的通用计算公式。 比如1323的欧拉函数:

varphi(1323)=varphi(3^3 imes7^2)=1323 imes(1-frac{1}{3})(1-frac{1}{7})

。 ##四、欧拉定理 欧拉函数的用处,在于欧拉定理:如果两个正整数

a

n

互质,则可以证明

n

的欧拉函数

varphi(n)

满足下面的等式:

a^{varphi(n)}equiv 1mod nLeftrightarrow a^{varphi(n)}\%n=1

也就是说

a

varphi(n)

次方被

n

除余数为1。 欧拉定理还有个特殊情况: 假设正整数

a

与质数

p

互质,因

varphi(p)=p-1

,则

a^{p-1}equiv 1mod p

。这就是著名的费马定理。 费马定理是欧拉定理的特例,而欧拉定理是RSA的核心。

在证明欧拉定理之前我们需要先介绍消去律。

  • 消去律 如果
gcd(p,q)=1

,则

acdot pmod q=bcdot pmod q Leftrightarrow amod q=bmod q

。 其中

gcd(p,q)

函数表示求

p

q

的最大公约数。 消去律非常简单,这里就不再进一步证明了。下面就用消去律来证明欧拉定理。 证明: 第一步,假设小于

n

且和

n

互质的数构成的集合为

Z_n

,则

|Z_n|=varphi(n)

。再令

Z_n={x_1,x_2,ldots,x_{varphi(n)}}

S={a*x_1mod n,a*x_2mod n,ldots,a*x_{varphi(n)}mod n}

,那么我们可以证明

Z_n=S

,理由如下: 首先,显然有

|Z_n|=|S|

; 然后,因为

a

n

互质,

x_i(1le ile varphi(n))

n

互质,所以

a*x_i

n

互质,所以

a*x_i mod nin Z_n

; 最后,假设

i eq j

,那么

x_i eq x_j

,且由

a

n

互质可得

a*x_jmod n eq a*x_j mod n

(消去律)。 第二步,由第一步的结论我们有如下推导:

a^{varphi(n)}*x_1*x_2*ldots*x_{varphi(n)}mod n
equiv((a*x_1)*(a*x_2)*ldots*(a*x_{varphi(n)}))mod n
equiv(a*x_1mod n)*(a*x_2mod n)*ldots*(a*x_{varphi(n)}mod n)
equiv x_1*x_2*ldots*x_{varphi(n)}mod n

对比等式的左右两端,因为

x_i(1le ile varphi(n))

n

互质,所以

a^{varphi(n)}mod n equiv 1 mod n equiv 1

(消去律)。 证毕。 ##五、模反元素 如果两个正整数

a

n

互质,那一定可以找到正整数

b

,使得:

abequiv1pmod n

,这时

b

就叫

a

的"模反元素”。比如,3和11互质,那3的模反元素是4,因为

3 imes4\%11=1

。显然,模反元素不止一个,4加减11的整数倍都是3的模反元素。即若

b

a

的模反元素,则

b+kn

都是

a

的模反元素。 欧拉定理可以用于证明模反元素必然存在:

a^{varphi(n)}=acdot a^{varphi(n-1)}equiv1pmod n

可以看到

a

varphi(n)-1

次方就是

a

的模反元素。 ##六、密钥生成步骤

A ightarrow B

通信: 第一步,随机选择两个不相等的质数

p

q

A

选择61和53(实际中,这两个质数越大,就越难破解)。 第二步,计算

p

q

的乘积

n

n=61 imes 53=3233

n

的长度就是密钥的长度。3233的二进制是110,010,100,001,一共有12位,所以密钥的长度为12位。实际应用中,RSA一般是1024位,重要场合为2048位。 第三步,计算

n

的欧拉函数

varphi(n)

varphi(n)=(p-1)(q-1)=60 imes52=3120

。 第四步,随机选择

e

,条件是

1<e<varphi(n)

,且

e

varphi(n)

互质。 随机选择了17(在实际应用中,常选择65537)。 第五步,计算

e

varphi(n)

的模反元素

d

edequiv1pmod{varphi(n)}

,于是找到模反元素

d

,实际上就是对下面一个二元一次方程求解:

ex+varphi(n)y=1,其中e=17,varphi(n)=3120.

这个方程可用"扩展欧几里得"求解,总之求解为

(x,y)=(2753,-15)

,即

d=2753

。 第六步,将

n

e

封装成公钥,

n

d

封装成私钥。在

A

的例子中,

n=3223

e=17

3573

,所以公钥是

(3233,17)

,私钥就是

(3233,2753)

。 ##七、可靠性

回顾密钥的生成步骤,一共出现了六个数字:

p

q

n

varphi(n)

e

d

。这六个数字中,公钥用到了

n

e

,其余四个都是不公开的。其中最关键的是

d

,因为

n

d

组成了私钥,一旦

d

泄露,就等于私钥泄露。那么,有无可能在已知

n

e

的情况下,推导出

d

呢?分析如下:

edequiv 1pmod{varphi(n)}

,所以只有知道

e

varphi(n)

,才能算出

d

varphi(n)=(p-1)(q-1)

,所以只有知道

p

q

,才能算出

varphi(n)

n=pq

,所以只有将

n

因数分解,才能算出

p

q

结论:如果

n

可以被因数分解,

d

就可以算出,也就意味着私钥被破解。可是,大整数的因数分解是一件非常困难的事情。目前,除了通过穷举进行暴力破解,没有其他有效的方法。 其实到这里,相信不少读者和我一样,总感觉暴力破解难度没那么大,因为我们可以穷举两个质数

p

q

,只要其乘积等于

n

,那密码不就被破解了么?让我们来看一下质数的数量吧。附: 一万以内质数,共1229个数 十万以内质数 十亿内的质数, 总个数:50847534 总和:24739512092254535 即十亿内的质数数量约为5千万,我们知道,32位的二进制能表示的最大数字为

4294967295(2^{32}-1)

,约40亿,而1024位甚至2048位的二进制能表示的最大数字

(2^{1024}-1)

(2^{2048}-1)

所包含的质数数量就多到难以用十进制表示。要想通过穷举两个质数

p

q

,其难度可想而知。 ##八、加密和解密

  • 1. 加密用公钥
(n,e)
B

要向

A

发送信息

m

,他用

A

的公钥

(n,e)

m

进行加密。这里需要注意的是,

m

必须是正数(字符串可以取ascii值或Unicode值)且

m

必须小于

n

。所谓“加密”,就是算出下式中的

c

m^eequiv cpmod n

A

的公钥是

(3233,17)

B

m

假设是65,则

65^{17}equiv2790pmod{3233}

,即

c=2790

  • 2. 解密用私钥
(n,d)
A

拿到

2790

后,用

(n,d)

(3233,2753)

进行解密,稍后我们将证明

c^dequiv mpmod n

一定成立。 说明:对于

m>n

时,有两种解决办法:一种是把长信息分割成若干短消息,每段分别加密;另一种是先选择一种“对称加密算法”,如DES,用这种算法对信息进行加密,再用RSA对DES加密。 ##九、私钥解密的证明

  • 即证明
c^dequiv mpmod n

成立。 证明:

ecause m^eequiv cpmod n

herefore c=m^e-kn

,则

c^d=(m^e-kn)^d

。 则等价于要证明:

m^{ed}equiv mpmod n

。 又

ecause ed=hvarphi(n)+1

herefore m^{ed}=m^{hvarphi(n)+1}

。 即等价于证明:

m^{hvarphi(n)+1}equiv mpmod n

。 分两种情况讨论:

(1)

m

n

互质时,由欧拉定理:

m^{varphi(n)}=1pmod n

herefore m^{hvarphi(n)+1}=mcdot(m^{varphi(n)})^hequiv mpmod n

(2)

m

n

不是互质关系时,由于

n

为质数

p

q

的乘积,所以必然有

m=kp

或者

m=kq

。不妨假设

m=kp

,其中

1le k<q

(因为前面已经假定

m<n

,所以

1le k<q

),则此时

k

q

必然互质(因为

1le k<q

,且

q

为质数,则比

q

小的任意正整数都与

q

互质),由此可知,

m

q

必然互质。根据欧拉定理:

m^{varphi(q)}=m^{q-1}equiv1pmod q

, 从而

m^{hvarphi(n)}=(m^{q-1})^{h(p-1)}equiv1pmod q

,于是存在正整数

s

,使得

m^{hvarphi(n)}=1+sq

。此式两边分别乘以

m=kp

,则

m^{hvarphi(n)+1}=m+skn

,从而

c^d=m^{hvarphi(n)+1}equiv mpmod n

。 证毕。 ##十、RSA运算相关的问题

  • 问题一:如何处理大数运算?
  • 问题二:如何求解同余方程
xy\%n=1

  • 问题三:如何快速进行模幂运算?
  • 问题四:如何获取大质数?

实际上,在实现RSA算法的过程中发现,问题二、三、四不是各自独立的,而是互有关联。

问题一的解决思路:将大数表示为一个

n

进制数组,对目前的32位系统而言,

n

最大值可以取值2的32次方减一,即取值范围为

0

~

(2^{32}-1)

。将一个1024位的大数转化为该

n

进制。该

n

进制下每一个符号就用一个32位的字(Dword)来表示。对该

n

进制的运算不过就是循环地对每一个符号对应的32位的字进行运算而已。

问题二:有欧几里得算法(辗转相除)。该算法可以用于求两个数的最大公约数。例如8和20的最大公约数求解过程如下:20%12=8,然后12%8=4,再然后8%4=0。因而20和12的最大公约数为4。

问题三:模幂运算是RSA的核心算法,最直接地决定了RSA算法的性能。针对快速模幂运算这一课题,西方现代数学家提出了大量的解决方案,通常都是先将模幂运算转化为模乘运算。例如,求

D=C^{15}\%N

等式中

D

的值: 由于

acdot b\%n=(a\%n)(b\%n)\%n

, 所以

C_1=Ccdot C\%N=C^2\%N
spacespacespacespacespacespace C_2=C_1cdot C\%N=C^3\%N
spacespacespacespacespacespace C_3=C_2cdot C_2\%N=C^6\%N
spacespacespacespacespacespace C_4=C_3cdot C\%N=C^7\%N
spacespacespacespacespacespace C_5=C_4cdot C_4\%N=C^{14}\%N
spacespacespacespacespacespace C_6=C_5cdot C\%N=C^{15}\%N

而对于

ab\%n

,如果A和B都是1024位的大数,那么

ab

就是2048位,所以要避免

acdot b

运算。由上面的例子可知,我们可以将多位乘法转换为一系列单位乘法和加法,即

acdot b\%n=(a\%ncdot b\%n)\%n \ (a+b)\%n=(a\%n+b\%n)\%n

到此,我们已经将模幂运算转换成了模乘运算的循环,那么要进一步提高RSA算法的效率,还需要提高模乘运算的效率。模乘过程中复杂度最高的环节是求模运算,因为一次除法实际上包含了多次加法、减法和乘法,如果在算法中尽量避免除法,则算法你效率会大大提高。著名的蒙哥马利算法是不含除法的模幂算法。

问题四:质数测试是RSA取密钥的第一步,但奇妙的是,其核心运算与加解密时所需的运算完全一致,即都是模幂运算。而模幂运算过程所需求解的欧几里得方程又恰恰是选取密钥第二步所需的运算。 ##十一、RSA在通信中的应用 RSA算法让双方可以在不安全的通信线路上进行秘密地通信,一切看上去似乎完美了。但在实际的应用中,我们还需要解决另外一个问题——中间人攻击:在A、B两人建立会话的过程中,攻击者很容易在线路中间操纵信息,让A、B两人误以为他们是在直接对话。让我们来看看这具体是如何操作的:

建立会话时,A首先呼叫B并索要B的公钥,此时,攻击者注意到了这个消息,当B将公钥传给A时,攻击者截断B的公钥,然后把攻击者自己的公钥传给A。接下来,A就给出了自己的密码,比如314159,然后用它收到的公钥进行加密,并将加密后的结果传给B。A以为他用的是B的公钥,但实际上他用的是攻击者的公钥。攻击者截获A传来的信息,用自己的私钥解出314159,再把314159用B的公钥加密后传给B。B收到信息后不会发现有什么异样,因为这段信息确实能用B的私钥解开,而且确实是314159(通过数据库匹配)。今后,A、B将会用314159作为密码进行通话,而完全不知道攻击者已掌握了密码。

怎么封住这个漏洞呢?我们得想办法建立一个获取对方公钥的可信渠道。一个简单而有效的办法是,建立一个所有人都信任的权威机构,由该机构来存储并分发大家的公钥。这就是我们通常所说的数字认证机构,英文是Certificate Authority,简称CA。任何人都可以申请把自己的公钥放到CA上去,不过CA必须亲自简称申请者是否符合资格。如果A想要和B建立会话,那A就直接从CA处获取B的公钥,这样就不用担心得到的是假公钥了。

新的问题又来了,怎么防止攻击者冒充CA呢?CA不但需要向A保证“这个公钥确实是B的”,还要向A证明,我确实是CA。

CA如何证明自己是CA呢?用“数字签名”。数字签名能够保证数据传输的完整性、发送者身份验证以及防止交易中的抵赖行为。 ##十二、数字签名及数字证书 这部分内容我本来打算自己写的,直到有一天我发现了一篇博文:一个故事教你看懂什么是数字证书,这篇博文用非常生动形象的例子解释了数字签名、数字证书以及HTTPS的工作原理,我这里如果再重复赘述就没有什么意义,想了解RSA算法在HTTPS中具体是如何应用的,强烈推荐这篇博文。 ##十三、相关链接