说说RSA加密解密的知识。
一般想到的加密方法就是移位,置换字符。比如A变成C,C变成E,如果给每个字母一个数字,比如A为1,B为2类推,用函数表示就是f(p)=(ap+b)mod 26,这种方法很容易被破解。RSA密码系统提供一个公开的加密密钥,但是保留解密密钥,这种方法目前来说非常安全,接下来我们就说说它的原理。
RSA是MIT的Ronald Rivest, Adi Shamir, and LeonardAdleman这三个人提出来的,其实在大英帝国的国家通讯总部工作的Clifford Cocks更早就提出来了,但是由于工作性质一直保密嘛,这种机构我们可以理解,可惜就是名字不是以他命名了。
加密
在RSA密码系统中,提供一个加密密钥(n,e),其中n=qp,n用来作为模数,相当于除数,p,q是两个非常大的素数,怎么也有个200位吧至少。e是用来作为指数,它和(p-1)(q-1)是互质的(relatively prime),也就是gcd(e,(p-1)(q-1))=1,他们没有公约数除了1(gcd就是最大公约数,可以看看我前面一篇求gcd的文章)。就现在的技术来说,找两个非常大的素数是比较容易的,而把一个非常大的数分解就不那么简单了,也就是找p,q容易,但是从n找p,q就难了。
那我们看看它的加密过程,假设有段消息M,我们把他转换成整数序列(就是a用00,b用01.....),然后把这些整数序列分割为等长的部分,比如都含有2N位数字,这里2N是使2N位个252525....的值不超过n的最大偶数,也就是2N位个字符换成的整数组合起来他大小不会超过n,原因我是认为可能是这样求模后的数值都是唯一的。这样M就分成了m1,m2,m3....这些部分。
接下来就是加密,利用的算法是(不知道怎么打幂数,只能这样看了)
C = M^e mod n
这样就完成了加密工作,得到了C,可以发送出去了。
解密
解密最重要的是要有解密的密钥d。
d是什么东西呢?它是e mod (p-1)(q-1) 的逆,什么叫模的逆呢?就是这样一个数a`,他和a的乘积aa`≡1 (mod m ),这里其实不是=号的,而是一个三横线的符号,叫做同余(后面如果mod是在括号内的都表示同余),打个比方a ≡b (mod m)指 a mod m = b mod m,也就是他们除以m的余数是相等的,这里就是aa' mod m 和 1 mod m 有相同的余数也就是1了,因为1 mod m就是1啊。
那这个数有什么用呢?我们看如果有这样一个d,那么就有de ≡1 (mod (p-1)(q-1)),也就是有一个整数k,他可以使得 de = k(p-1)(q-1) +1 ,这样就有 (写^实在不方便阅读,大家可以拿起纸笔自己写一下更直观)
C^d ≡(M^e)^d (mod n) = M^ed ≡M^(1+k(p-1)(q-1)) (mod n)
根据费马的小数理论(又是个新东西,其实很简单的理论,当然证明就呵呵),即如果p是一个素数,a是一个不能整除p的整数,那么 a^(p-1) ≡1 (mod p),再假设gcd(M,p) = gcd(M,q) =1(这只在极其个别情况下不成立,不解释过多),那么就有M^(p-1) ≡1 (mod p) 和 M^(q-1) ≡1 (mod q),这样就有
C^d ≡M*M^(p-1)k(q-1) =M *1 (mod p)
C^d ≡M*M^(q-1)k(p-1) =M *1 (mod q)
其实这里我有点不理解,估计是前面学习模数的性质没有好好看,就是前面是C^d = M^de (mod n) 现在又可以换成 C^d ≡M^de (mod p),我认为可能是因为n = pq,这里面可以转换证明一下吧。好吧,我自己证明了一下(不关心的可以自行跳过,让我自己自娱自乐吧):
假设有 a ≡b (mod n) ,其中 n=pq,那么是否a ≡b (mod p)?
根据假设我们有 a mod n = b mod n ,也就是存在 k1 和 k2 使得
a - k1*n = b - k2*n 即 a - b = k1*n - k2*n = n( k1- k2) = pq(k1-k2) = p( k1*q - k2*q)
假设k1*q = x1 ,k2*q = x2,那么
a - b = x1*p - x2*p 即 a - x1*p = b - x2*p
所以a mod p = b mod p ,得证!哈哈。
接着我们上面的,这里用到中国余数定理,是这样说的
设m1,m2,...,mk是两两互素的正整数,即gcd(mi,mj) =1,i≠j,i,j = 1,2,...,k
则同余方程组:
x≡b1 (mod m1)
x≡b2 (mod m2)
...
x≡bk (mod mk)
模[m1,m2,...,mk]有唯一解,即在[m1,m2,...,mk]的意义下,存在唯一的x,满足:
x≡bi mod [m1,m2,...,mk],i = 1,2,...,k
也就有:C^d≡M (mod pq) 也就是C^d ≡ M (mod n),这里注意到M (mod n) 其实就等于M,这由前面分块时候M
这样我们就得到了解密的方法,即 M = C^d mod n。
举例子。以后有时间再加吧,主要是个概念。
我们知道,找到两个大素数p,q和与(p-1)(q-1)互质的e是比较简单的,知道了p,q,也很容易通过欧几里德算法来求出e mod (p-1)(q-1)的逆,但是知道n求p,q是非常困难的,不信你拿个10位的试试。所以RSA是发展的比较好的加密方法,很多地方用。
再说说密码协议(Cryptographic Protocols),密码协议可以保证两人之间在未加密的通道上传输加密信息,也可以数字签名的功能。
假设有两个人从来没有联系过,他们怎么产生一个共用的key呢?Diffie-Hellman key agreement protocol 就是解决这个问题的。假设我和你想共用一个公共密钥,那么我们可以这么做:
1.我们都同意使用素数p和一个p的原根a (原根概念请维基百度之)
2.我选了一个自己知道的整数k1,然后把a^k1 mod p 发给你
3.你也选一个整数k2,然后把a^k2 mod p发给我
4.我算出 a^(k2*k1) mod p, 你算出 a^(k1*k2) mod p,两个其实是一样的
这样我们就有了公共key了,虽然p,a,a^k1 mod p,a^k2 mod p的值暴露了,但是只要k1,k2没人知道,那公共密钥a^(k2*k1) mod p就没人知道了。要破解,只能从a^k1 mod p,a^k2 mod p里面解出k1,k2来,这难度您想想吧。
数字签名就是保证信息来源自正确的那个人。简单说说实现方法,假设我有公共密钥(n,e),一个只有我自己知道的解密密钥d,我加密的话是采用E(n,e)(x) = x^e mod n,.解密是采用方程D(n,e) = x^d mod n。那怎么实现数字签名呢,其实很简单,我只要把信息采用解密方程来加密,就是使用D(n,e)对信息进行处理,然后把得到的数据再发送出去,当接受者收到信息时,采用加密方程来解密,也就是E(n,e)(D(n,e)) = x,这样既可以保证信息是加密的,又保证了信息的来源。那同样的,如果双方都有各自的公共密钥和解密密钥,那么我们就可以先用自己的解密密钥来添加签名,然后用接受者的公共密钥来加密信息,这样得到的数据既是签名的也是加密过的,接受者收到信息后,先用自己的解密密钥来解密,然后用发送者的公共密钥来解密,这样就好了。原理还是挺简单的吧。
(以上信息参考了《离散数学及其应用》一书)