非对称密码体制
- 格式:doc
- 大小:178.50 KB
- 文档页数:10
什么是公钥密码体制
公钥密码体制也称非对称密码体制或者双钥密码体制,是基于数学函数(如单向陷门函数)而不是基于置换和代换的工具。
公钥密码算法的最大特点是采用两个相关密钥将加密和解密能力分开,其中一个是公开的,称为公钥,用于加密;其中一个是为用户专用的,是保密的,称为私钥,用于解密。
公钥密码体制是为了解决对称密码体制中最难解决的2个问题而提出的:
1.密钥分配问题:在对称密码中,接受方和发送方使用相同密钥。
一般情况下该密钥
通过加密信道进行传输。
但是加密信道可能会被攻击者攻击。
2.数字签名问题:如果使用对称加密来进行数字签名,那么在对密钥进行管理和分发
时带来被攻击者攻击的问题。
在公钥密码体制中存在2个密钥:公钥,私钥。
公钥和加密算法是公开的,公钥用于加密数据;私钥是保密的,用于解密。
以上内容仅供参考,如需获取更多详细信息,建议查阅公钥密码体制相关的资料或咨询数学领域专业人士。
对称密码体制和非对称密码体制的特点比较?密码体制分为私用密钥加密技术(对称加密)和公开密钥加密技术(非对称加密)。
(一)、对称密码体制对称密码体制是一种传统密码体制,也称为私钥密码体制。
在对称加密系统中,加密和解密采用相同的密钥。
因为加解密密钥相同,需要通信的双方必须选择和保存他们共同的密钥,各方必须信任对方不会将密钥泄密出去,这样就可以实现数据的机密性和完整性。
比较典型的算法有DES(Data Encryption Standard数据加密标准)算法及其变形Triple DES(三重DES),GDES(广义DES);欧洲的IDEA;日本的FEAL N、RC5等。
DES标准由美国国家标准局提出,主要应用于银行业的电子资金转帐(EFT)领域。
DES的密钥长度为56bit。
Triple DES 使用两个独立的56bit密钥对交换的信息进行3次加密,从而使其有效长度达到112bit。
RC2和RC4方法是RSA数据安全公司的对称加密专利算法,它们采用可变密钥长度的算法。
通过规定不同的密钥长度,,C2和RC4能够提高或降低安全的程度。
对称密码算法的优点是计算开销小,算法简单,加密速度快,是目前用于信息加密的主要算法。
尽管对称密码术有一些很好的特性,但它也存在着明显的缺陷,包括: l)进行安全通信前需要以安全方式进行密钥交换。
这一步骤,在某种情况下是可行的,但在某些情况下会非常困难,甚至无法实现。
例如,某一贸易方有几个贸易关系,他就要维护几个专用密钥。
它也没法鉴别贸易发起方或贸易最终方,因为贸易的双方的密钥相同。
另外,由于对称加密系统仅能用于对数据进行加解密处理,提供数据的机密性,不能用于数字签名。
因而人们迫切需要寻找新的密码体制。
2)规模复杂。
(二)、非对称密码体制非对称密码体制也叫公钥加密技术,该技术就是针对私钥密码体制的缺陷被提出来的。
在公钥加密系统中,加密和解密是相对独立的,加密和解密会使用两把不同的密钥,加密密钥(公开密钥)向公众公开,谁都可以使用,解密密钥(秘密密钥)只有解密人自己知道,非法使用者根据公开的加密密钥无法推算出解密密钥,顾其可称为公钥密码体制。
云南大学数学与统计学实验教学中心实验报告一、实验目的:通过实验掌握非对称密码体制的重要思想。
二、实验内容:查阅资料,实现RSA密码体制的编码算法、译码算法、密钥生成算法查阅资料,实现ECC密码体制的编码算法、译码算法、密钥生成算法三、实验环境Win7、Eclipse四、实验过程(请学生认真填写):实验过程、结果以及相应的解释:1. 预备知识非对称密码体制也叫公钥加密技术,该技术就是针对私钥密码体制的缺陷被提出来的。
在公钥加密系统中,加密和解密是相对独立的,加密和解密会使用两把不同的密钥,加密密钥(公开密钥)向公众公开,谁都可以使用,解密密钥(秘密密钥)只有解密人自己知道,非法使用者根据公开的加密密钥无法推算出解密密钥,顾其可称为公钥密码体制。
如果一个人选择并公布了他的公钥,另外任何人都可以用这一公钥来加密传送给那个人的消息。
私钥是秘密保存的,只有私钥的所有者才能利用私钥对密文进行解密。
公钥密码体制的算法中最著名的代表是RSA系统,此外还有:背包密码、McEliece密码、Diffe_Hellman、Rabin、零知识证明、椭圆曲线、EIGamal算法等。
公钥密钥的密钥管理比较简单,并且可以方便的实现数字签名和验证。
但算法复杂,加密数据的速率较低。
公钥加密系统不存在对称加密系统中密钥的分配和保存问题,对于具有n个用户的网络,仅需要2n个密钥。
公钥加密系统除了用于数据加密外,还可用于数字签名。
2. 实验过程(一)RSA加密算法A、原理分析:RSA的具体计算算法:假设Alice想要通过一个不可靠的媒体接收Bob的一条私人讯息。
她可以用以下的方式来产生一个公钥和一个私钥:1.随意选择两个大的质数p和q,p不等于q,计算N=pq。
2.根据欧拉函数,求得r= φ(n) = φ(p)φ(q) = (p-1)(q-1)3.选择一个小于r的整数e,求得e关于模r的模反元素,命名为d。
(模反元素存在,当且仅当e与r互质)4.将p和q的记录销毁。
(N,e)是公钥,(N,d)是私钥。
Alice将她的公钥(N,e)传给Bob,而将她的私钥(N,d)藏起来。
加密消息假设Bob想给Alice送一个消息m,他知道Alice产生的N和e。
他使用起先与Alice约好的格式将m转换为一个小于N的整数n,比如他可以将每一个字转换为这个字的Unicode码,然后将这些数字连在一起组成一个数字。
假如他的信息非常长的话,他可以将这个信息分为几段,然后将每一段转换为n。
用下面这个公式他可以将n加密为c:计算c并不复杂。
Bob算出c后就可以将它传递给Alice。
解密消息Alice得到Bob的消息c后就可以利用她的密钥d来解码。
她可以用以下这个公式来将c转换为n:得到n后,她可以将原来的信息m重新复原。
解码的原理是以及ed ≡1 (mod p-1)和ed ≡ 1 (mod q-1)。
由费马小定理可证明(因为p和q是质数)和这说明(因为p和q是不同的质数,所以p和q互质)注:本内容参考维基百科RSA加密算法,可能与老师说的有略微不同。
B、具体代码如下://具体实现的代码//RSA实现时候用大数数来做比较简单public class RSA1 {private final static SecureRandom random = new SecureRandom();private static BigInteger d; // 为私钥{d,n}中的dprivate static BigInteger e; // 其实就是公钥 <e,n>中的eprivate static BigInteger n; // 为公开的 p x qprivate static BigInteger p; // 需要保密的大素数 p qprivate static BigInteger q;/*** 产生长度为N位的公钥和私钥* @param N*/public void genKey(int N) {// 产生两个N/2位的大素数p和qp = BigInteger.probablePrime(N / 2, random);q = BigInteger.probablePrime(N / 2, random);// 计算(p-1)*(q-1)BigInteger phi =(p.subtract(BigInteger.ONE)).multiply(q.subtract(BigInteger.ONE));// 计算模数p*qn = p.multiply(q);// 随便找一个b,使得gcd(b, phi) =1;// 通用的公钥是2^16 + 1=65537e = new BigInteger("65537");// 计算出a,即b的模n逆d = e.modInverse(phi);}/*** 加密函数* @param plainText* 明文* @return密文*/public byte[] encrypt(byte[] plainText) {return new BigInteger(plainText).modPow(e,n).toByteArray();}/*** 解密函数* @param cipherText* 密文* @return明文*/public byte[] decrypt(byte[] cipherText) {return new BigInteger(cipherText).modPow(d,n).toByteArray();}public static void main(String[] args) throws FileNotFoundException,IOException, ClassNotFoundException {RSA1 rsa = new RSA1();rsa.genKey(128); // 产生密钥// 加密一句消息byte[] cipher = rsa.encrypt("hello word".getBytes());System.out.println("RSA 加密:" + new String(cipher));// 解密byte[] plain = rsa.decrypt(cipher);System.out.println("RSA 解密:" + new String(plain));}}结果如下:运行时候,主要的是以下代码:运行结果如下图://得到结果与真实结果一样。
说明正确(二)ECC加密算法A、原理分析:椭圆曲线密码学(Elliptic curve cryptography,缩写为ECC)是基于椭圆曲线数学的一种公钥密码的方法。
椭圆曲线在密码学中的使用是在1985年由Neal Koblitz和Victor Miller分别独立提出的。
ECC的主要优势是在某些情况下它比其他的方法使用更小的密钥——比如RSA加密算法——提供相当的或更高等级的安全。
ECC的另一个优势是可以定义群之间的双线性映射,基于Weil 对或是Tate对;双线性映射已经在密码学中发现了大量的应用,例如基于身份的加密。
不过一个缺点是加密和解密操作的实现比其他机制花费的时间长。
ECC的具体计算算法:a)密钥的生成Bob(使用者)执行了下列计算:i) 在区间[1,n-1]中随机选取一个整数d。
ii) 计算点Q=dP (d个P相加)iii) Bob公开自己的公开密钥(E(Fq),p,n,Q)iv) Bob的私钥为整数d。
Alice要发送消息m给Bob,Alice执行:i) 查找Bob的公钥(E(Fq),p,n,Q),ii) 将m表示成一个域元素m∈Fq,iii) 在区间[1,n-1]内选取一个随机数k,iv) 依据Bob的公钥计算点(x1,y1)=kP(k个P相加)v) 计算点(x2,y2)=kQ,如果x2=0,则回到第iii)步Ⅵ)计算C=mx2Ⅶ)传送加密数据(x1,y1,C)给Bobb) Bob的解密过程Bob收到Alice的密文(x1,y1,C)后,执行i) 使用私钥d,计算点(x2,y2)=d(x1,y1)通过计算m=C*x2,恢复出明文数据B、具体代码如下://具体实现的代码package ECC;public class ECC {private int a, p;private POINT ukAlpha, ukBeta;private int rKey;/*** Method ECCImpClass*/public ECC(int a, int p, int priK, POINT alpha) { this.a = a;this.p = p;this.rKey = priK;Alpha = alpha;this.generatingUkBeta();}/*** 欧几里得算法--求逆元*/public int[] euclid(int x0, int y0) {int x, y, a, b, c, d, pa, pb, pc, pd, q, r;int[] res = new int[2];x = x0;y = y0;pa = 1;pb = 0;pc = 0;pd = 1;a = 1;b = 0;c = 0;d = 1;while (y != 0) {r = x % y;q = (x - r) / y;a = pc;b = pd;c = pa - q * pc;d = pb - q * pd;x = y;y = r;pa = a;pb = b;pc = c;pd = d;}if (a < 0) {a = a + y0;}res[0] = x;res[1] = a;return res;}/*** 求bmod p 下的逆元** @param a* @param b* @param p* @return*/public int aUpBModP(int a, int b, int p) { int invB, res1;a = a % p;b = b % p;int[] res = this.euclid(b, p);//System.out.println("b mod p 的逆元:" + res[1]);invB = res[1];res1 = (a * invB) % p;if (res1 < 0) {res1 = res1 + p;}return res1;}/*** 求2P** @param pt* @return*/public POINT doublePoints(POINT pt) {int x1, y1, x2, y2, lambda, n1, n2;x1 = pt.getX();y1 = pt.getY();n1 = 3 * x1 * x1 + this.a;n2 = 2 * y1;lambda = this.aUpBModP(n1, n2, this.p);x2 = (lambda * lambda - 2 * x1) % (this.p);y2 = ((x1 - x2) * lambda - y1) % (this.p);if (x2 < 0) {x2 = x2 + this.p;}if (y2 < 0) {y2 = y2 + this.p;}return new POINT(x2, y2);}/*** 求nP** @param m* @param pt* @return*/public POINT anyPoint(int m, POINT pt) { int k;if (m == 1)return pt;else if (m == 2)return this.doublePoints(pt);else {if (m % 2 == 0) {k = m / 2;POINT p1 = this.doublePoints(pt);return this.anyPoint(k, p1);} else {POINT p1 = this.anyPoint(m - 1, pt);return this.add2Points(pt, p1);}}}/*** 两个点相加** @param p1* @param p2* @return*/public POINT add2Points(POINT p1, POINT p2) { int x1, y1, x2, y2, x3, y3, lambda, n1, n2;if (p1.isSamePoint(p2))return this.doublePoints(p1);x1 = p1.getX();y1 = p1.getY();x2 = p2.getX();y2 = p2.getY();n1 = y2 - y1;n2 = x2 - x1;lambda = this.aUpBModP(n1, n2, this.p);x3 = (lambda * lambda - x1 - x2) % (this.p);y3 = ((x1 - x3) * lambda - y1) % (this.p);if (x3 < 0) {x3 = x3 + this.p;}if (y3 < 0) {y3 = y3 + this.p;}return new POINT(x3, y3);}/*** Beta = d * alpha 生成*/public void generatingUkBeta() {Beta = this.anyPoint(this.rKey, Alpha);}public POINT getUkBeta() {return Beta;}/*** 加密点pt** @param pt* @param ranK* @return*/public POINT[] encripting(POINT pt, int ranK) { POINT[] ct = new POINT[2];ct[0] = this.anyPoint(ranK, Alpha); // k*PPOINT temp = this.anyPoint(ranK, Beta);//k*Q=(x2,y2)ct[1] = this.anyPoint(temp.getX(), pt);// c = mx2return ct;}/*** 解密** @param ct* @return*/public POINT decripting(POINT[] ct) {POINT p1, p2, p3;p1 = new POINT();p1.setX(ct[0].getX());p1.setY(ct[0].getY());p2 = this.anyPoint(this.rKey, p1);// (x2,y2)int[] res = this.euclid(p2.getX(), this.p);p3 = this.anyPoint(res[1], ct[1]);// p3 = this.add2Points(ct[1], p2);return p3;}/*** Method main** @param args*/public static void main(String[] args) {System.out.println("\nTesting the ecc:");System.out.println("——对(5, 19)加密——");ECC ecc3 = new ECC(1, 23, 9, new POINT(3, 13));POINT beta = ecc3.getUkBeta();System.out.println("公钥,Q=(" + beta.getX() + "," + beta.getY() + ")");POINT[] ct = ecc3.encripting(new POINT(5, 19), 5);System.out.println("(x1,y1) = ("+ ct[0].getX() + ","+ ct[0].getY()+ ")");System.out.println("(x2,y2) = ("+ ct[1].getX() + ","+ ct[1].getY()+ ")");POINT x = ecc3.decripting(ct);System.out.println("解密(" + x.getX() + "," + x.getY() + ")");}}// 点类class POINT {private int x, y;public POINT() {}public POINT(int x, int y) {this.x = x;this.y = y;}public void setX(int x) {this.x = x;}public void setY(int y) {this.y = y;}public int getX() {return x;}public int getY() {return y;}public boolean isSamePoint(POINT p) {if (x == p.getX() && y == p.getY()) {return true;} else {return false;}}public void printPoint() {System.out.println("The point is (" + this.x + "," + this.y + ")");}public POINT signPoint() {return new POINT(-this.x, -this.y);}}结果如下:运行时候,主要的是以下代码:五、实验总结1.遇到的问题及分析:遇到问题:ECC中在求几点P的素数阶n是不会求分析并解决:-查阅资料也没有解决,后来想了到找了一个k>>n的一个数,这样来解决,但是个人感觉不太严谨。