RSA算法

从本节起,我们利用前面的数学知识,推导公钥密码学中的重要加解密算法:RSA算法。

从数学上来讲,解密是加密的逆函数,如果用函数f来表示加密,函数g表示解密,则对于任意明文c,都有g(f(c))=c。
而且加密函数f要容易计算,解密函数g则需要带有秘密的参数(即私钥)才能计算。

在正式开始之前,我们回顾一下现在走到了哪里。

我们得到了集合Zn,其元素是等价类,比如[0]、[-2]、[3]等。为了表述方便,在每个等价类中分别选择一个典型的元素作为等价类的代表。
不出意外,它们分别是0、1、2、……、n-1共n个元素。Zn关于运算+和*构成含厶有限交换环,注意这里的交换是针对乘法运算*而言。

为了保持运算+和*(请注意它们的初始定义都是基于等价类[.]本身)的不变,我们推导得到这n个元素之间的运算法则的结果
简言之,就是把它们的和(或积)除以n得到的余数(或者称为模n的余数)

然后我们又给出定义Zn*≡{[k]|(k,n)=1},并且有结论:Zn*关于*运算构成乘法群。
注意到Zn*是个有限群,那么它的阶(即元素个数)是多少呢?由定义可知,其个数就是小于n并且与n互素的正整数的个数。
数学上专门用一个函数,来表示小于n并且与n互素的正整数的个数,称为欧拉函数,用符号ψ(n)表示。

回顾前面提到的、关于有限群G和G中任意元素a的两个定理:
1、设|a|=m,则对于任意正整数n,an=1←→m|n
2、G中任一元素的阶整除|G|
因而对于Zn*中的任意元素a,有aψ(n)=1,或者a(ψ(n)+1)=a。
--说明:上面的等号是表示两边的数都模n取余数,结果相等。
  在大多数教科书中,都记为aψ(n)=1(mod n)(在数论中,称为欧拉定理),后面我们也将采用这种书写形式。

推导到这里,仍没有什么进展。

突然,思路来了,如果我们把指数(ψ(n)+1)拆成两个数e和d的乘积,即a(ψ(n)+1)=a(e*d)=a(mod n)
注意到指数运算的特殊性a(e*d)=(ae)d,如果求幂运算(.)e作为加密函数f公开(注意要同时公布e和n作为公钥),
(.)d作为解密函数g(d作为对应的私钥),不就得到了等式g(f(a))=a吗

别高兴太早,还有2个问题未解决:
1、如何保证私钥d的安全?
2、对于与n不互素的数,上述等式成立吗?

对于问题1,先考虑最简单的情况,n是素数p,则可以计算ψ(n)即ψ(p),但这样的话,根据e(注意它是公开的),就可以推算出私钥d,失败。
好了,那再稍微复杂一点,取n为素数p和q的乘积,即n=p*q,这时公开的仍是e和n,要计算私钥d需要知道ψ(n)
幸运的是,仅由e和n推导不出ψ(n),从而也得不出d,私钥d的安全性得到保证。注意,私钥的持有者知道n的因式分解,因而知道d,从而可以解密。
现在,私钥的安全性取决于整数的因式分解的难度。如果可以直接由n分解出p和q,就可以通过计算出ψ(n)而得到私钥d。
再次幸运的是,将两个很大素数的乘积进行因式分解,是十分困难的。--说明:此时ψ(n)=(p-1)(q-1)

问题2,很幸运,这依然成立,即对于任意a(a可以与n不互素),a(ψ(n)+1)=a(e*d)=a(mod n),证明过程参见一般教科书。

补充说明:对于e,d的选择,前面是说取(ψ(n)+1)=e*d,事实上对于任意整数k,只要e,d满足k*ψ(n)+1=e*d,都可以使上述加解密的等式成立。
换句话说,我们选择一个小于并且与(p-1)(q-1)互素的正整数e,然后计算满足d*e≡1(mod ψ(n))的正整数d(也称为求模ψ(n)的逆)

验证过程:a(k*ψ(n)+1)=a(e*d)=a(mod n)

如果时光能够倒流到上个世纪70年代早期,你能够想到这个办法,那么恭喜你,你将在2000年获得计算机界的最高奖项--图灵奖。