RSA公钥加密+(Euclid)欧几里德扩展算法

来源:互联网 发布:万能五笔 for mac os 编辑:程序博客网 时间:2024/05/17 23:17

RSA加密算法


RSA简介

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。但在分布式计算和量子计算机理论日趋成熟的今天,RSA加密安全性受到了挑战。

RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

RSA确定公钥和私钥步骤

(1)选择p,q,其中p,q为大素数。

(2)计算乘积n=p*q。

(3)求小于n且与n互质的数的个数,利用欧拉函数得到ϕ (n)=(p-1)(q-1)。

(4)随机选择整数e, 使 gcd(ϕ (n),e)=1,1<e<ϕ (n)。

(5)计算d,使d ≡ e -1mod ϕ(n)。

然后将(n,e)公开作为公钥PK(public key),将(p,q,d)私藏作为私钥SK(secret key)。

加密解密操作

(1)加密 (用e,n)

明文:0<M<n

密文:C≡M e (mod n)

(2)解密 (用d,n)

密文:C

明文:M ≡ C d (mod n)


扩展欧几里德算法解线性同余方程


其实在RSA产生密钥的过程中,最困难的一步就是通过e来获得d。因为这里需要用到扩展欧几里德算法来求线性同余方程,在讲述扩展欧几里德算法之前我先讲述欧几里德算法。

欧几里德算法

欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。

对于整数a,b一定存在这样的关系:a = kb+r。

而欧几里德算法是:gcd(a,b) = gcd(b,a%b)等同于gcd(a,b) = gcd(b,r)。

举个例子:求8和6的最大公约数。

gcd(8,6) = gcd(6,8%6) = gcd(6,2):也就是说8和6的最大公约数与6和2的最大公约数是一致的。

扩展欧几里德算法

扩展的欧几里德算法:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。

ax+by = gcd(a , b)

bx1+(a%b)x2 = gcd(b ,a%b)

.......

这样一直递推下去,直到a%b的这一项为0的时候停止,这是可以设置xn = 1 , 设置yn为任意数,一般我们设置为0。

由于根据欧几里德算法,每一个等式右边都是相等的,所以对于第一个第二个等式我们可以得到递推公式,求解过程如下:

ax + by = bx1 + (a%b)y1

             = bx1 + (a – (a/b)*b)y1

             = bx1 + ay1 – (a/b)y1*b

             = ay1+ (x1 – (a/b)y1)*b

所以递推公式为:x = x1 , y = x1– (a/b)y1


RSA结合扩展欧几里德算法


其实到这里,有些人一定还是比较困惑求解d和扩展欧几里德算法关系到底在哪。下面就来解决这个问题:

在确定RSA密钥的第五个步骤中,是:d ≡ e-1mod ϕ(n)

将其做简单的变形为:ed ≡ 1 mod ϕ(n)。也就是ed mod ϕ(n) = 1。还记得欧几里德算法中说:对于整数a,b都可以写成a = kb+r,那么可以将ed mod ϕ(n) = 1继续写成ed - ϕ(n)k = 1。这样将d看成是x,k看作是y,所以求解d的过程也就是求解扩展欧几里德算法中的x的过程。

下面给出用java实现RSA算法的代码:

import java.math.BigInteger;public class RSASystem {private BigInteger n = null;private BigInteger p = null;private BigInteger q = null;private BigInteger totient = null;//欧拉函数private BigInteger e = null;private BigInteger d = null;public RSASystem(BigInteger p, BigInteger q){this.p = p;this.q = q;setKey();}public void setKey(){this.n = p.multiply(q);this.totient = (p.subtract(BigInteger.valueOf(1))).multiply(q.subtract(BigInteger.valueOf(1)));this.e = getE();BigInteger[] temp = eGcd(e, totient);d = temp[0];}private BigInteger[] eGcd(BigInteger a, BigInteger b){BigInteger[] result = new BigInteger[2];if(b.compareTo(BigInteger.valueOf(0)) == 0){result[0] = BigInteger.valueOf(1);result[1] = BigInteger.valueOf(0);return result;}BigInteger[] temp = eGcd(b, a.mod(b));result[0] = temp[1];result[1] = temp[0].subtract((a.divide(b)).multiply(temp[1]));return result;}private BigInteger getE() {return totient.divide(BigInteger.valueOf(4)).nextProbablePrime();}/** * RSA加密函数 * @param m需要进行加密操作的明文 * @return */public BigInteger encode(BigInteger m){return m.modPow(this.e, this.n);}/** * RSA解密函数 * @param c 需要进行解密操作的密文 * @return */public BigInteger decode(BigInteger c){return c.modPow(this.d, this.n);}public static void main(String[] args) {RSASystem rsa = new RSASystem(BigInteger.valueOf(47), BigInteger.valueOf(71));System.out.println("rsa n:"+rsa.n);System.out.println("rsa totient:"+rsa.totient);System.out.println("rsa e:"+ rsa.e);System.out.println("rsa d:"+ rsa.d);System.out.println(rsa.encode(BigInteger.valueOf(40)));System.out.println(rsa.decode(BigInteger.valueOf(2722)));}}
其中BigInteger[] eGcd(BigInteger a, BigInteger b)方法就是使用递归的方法来实现扩展欧几里德算法的求解,最后的放回结果是一个数组,数组的的一个元素就是x的值,第二个元素就是y的值。



0 0
原创粉丝点击