非对称密码体制.docx
《非对称密码体制.docx》由会员分享,可在线阅读,更多相关《非对称密码体制.docx(15页珍藏版)》请在冰豆网上搜索。
非对称密码体制
云南大学数学与统计学实验教学中心实验报告
课程名称:
计算机网络实验
学期:
2012-2013学年第二学期
成绩:
指导教师:
陆正福
学生姓名:
卢富毓
学生学号:
20101910072
实验名称:
非对称密码体制
实验要求:
必做
实验学时:
4学时
实验编号:
No.14
实验日期:
2013/3/28
完成日期:
2013/6/28
学院:
数学与统计学院
专业:
信息与计算科学
年级:
2010级
一、实验目的:
通过实验掌握非对称密码体制的重要思想。
二、实验内容:
查阅资料,实现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(modp-1)和ed≡1(modq-1)。
由费马小定理可证明(因为p和q是质数)
和
这说明(因为p和q是不同的质数,所以p和q互质)
注:
本内容参考维基百科RSA加密算法,可能与老师说的有略微不同。
B、具体代码如下:
//具体实现的代码
//RSA实现时候用大数数来做比较简单
publicclassRSA1{
privatefinalstaticSecureRandomrandom=newSecureRandom();
privatestaticBigIntegerd;//为私钥{d,n}中的d
privatestaticBigIntegere;//其实就是公钥中的e
privatestaticBigIntegern;//为公开的pxq
privatestaticBigIntegerp;//需要保密的大素数pq
privatestaticBigIntegerq;
/**
*产生长度为N位的公钥和私钥
*@paramN
*/
publicvoidgenKey(intN){
//产生两个N/2位的大素数p和q
p=BigInteger.probablePrime(N/2,random);
q=BigInteger.probablePrime(N/2,random);
//计算(p-1)*(q-1)
BigIntegerphi=(p.subtract(BigInteger.ONE)).multiply(q
.subtract(BigInteger.ONE));
//计算模数p*q
n=p.multiply(q);
//随便找一个b,使得gcd(b,phi)=1;
//通用的公钥是2^16+1=65537
e=newBigInteger("65537");
//计算出a,即b的模n逆
d=e.modInverse(phi);
}
/**
*加密函数
*@paramplainText
*明文
*@return密文
*/
publicbyte[]encrypt(byte[]plainText){
returnnewBigInteger(plainText).modPow(e,n).toByteArray();
}
/**
*解密函数
*@paramcipherText
*密文
*@return明文
*/
publicbyte[]decrypt(byte[]cipherText){
returnnewBigInteger(cipherText).modPow(d,n).toByteArray();
}
publicstaticvoidmain(String[]args)throwsFileNotFoundException,
IOException,ClassNotFoundException{
RSA1rsa=newRSA1();
rsa.genKey(128);//产生密钥
//加密一句消息
byte[]cipher=rsa.encrypt("helloword".getBytes());
System.out.println("RSA加密:
"+newString(cipher));
//解密
byte[]plain=rsa.decrypt(cipher);
System.out.println("RSA解密:
"+newString(plain));
}
}
结果如下:
运行时候,主要的是以下代码:
运行结果如下图:
//得到结果与真实结果一样。
说明正确
(二)ECC加密算法
A、原理分析:
椭圆曲线密码学(Ellipticcurvecryptography,缩写为ECC)是基于椭圆曲线数学的一种公钥密码的方法。
椭圆曲线在密码学中的使用是在1985年由NealKoblitz和VictorMiller分别独立提出的。
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)给Bob
b)Bob的解密过程
Bob收到Alice的密文(x1,y1,C)后,执行
i)使用私钥d,计算点(x2,y2)=d(x1,y1)
通过计算m=C*x2,恢复出明文数据
B、具体代码如下:
//具体实现的代码
packageECC;
publicclassECC{
privateinta,p;
privatePOINTukAlpha,ukBeta;
privateintrKey;
/**
*MethodECCImpClass
*/
publicECC(inta,intp,intpriK,POINTalpha){
this.a=a;
this.p=p;
this.rKey=priK;
this.ukAlpha=alpha;
this.generatingUkBeta();
}
/**
*欧几里得算法--求逆元
*/
publicint[]euclid(intx0,inty0){
intx,y,a,b,c,d,pa,pb,pc,pd,q,r;
int[]res=newint[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;
returnres;
}
/**
*求bmodp下的逆元
*
*@parama
*@paramb
*@paramp
*@return
*/
publicintaUpBModP(inta,intb,intp){
intinvB,res1;
a=a%p;
b=b%p;
int[]res=this.eucl