一 密钥分配.docx
《一 密钥分配.docx》由会员分享,可在线阅读,更多相关《一 密钥分配.docx(27页珍藏版)》请在冰豆网上搜索。
一密钥分配
实习一密钥分配
一、实习目的
1.理解密钥管理的重要性;
2.掌握对称密码和公钥密码密钥管理的不同特性;
3.掌握密钥分发基本方法,能设计密钥分发方案
二、实习要求
1.实习前认真预习第2章的有关内容;
2.复习对称密码和公钥密码相关内容;
3.熟悉Java平台的JCE包有关类。
三、实习内容
假定两个用户A、B,用户A、B的通讯密钥为K,他们的公私钥对分别是KPUa、KPRa和KPUb、KPRb,他们要进行安全通讯,密钥分发与通信过程如1所示。
(1)根据图1所示,实现利用公钥密码算法分发对称密钥的过程。
实现的阶梯任务如下:
以本地两个目录模拟两个用户,采用变量方式直接实现密钥的分发;
实现算法的图形化方式,用户可以选择算法、参数、工作模式等;
以文件方式管理密钥及明文、密文;
采用Socket,建立安全通信过程;
将方案移植到某个web应用中。
(2)按照
(1)的阶梯任务,实现基于DH密钥协定的密钥分发。
四、实验过程
1.知识回顾
DES是数据加密标准(DataEncryptionStandard)的简称,出自IBM的研究工作,并在1977年被美国政府正式采纳。
它是使用较为广泛的密钥系统,最初开发DES是嵌入硬件中DES特别是在保护金融数据的安全,如自动取款机中,使用较多。
在DES中,使用了一个56位的密钥以及附加的8位奇偶校验位,产生最大64位的分组大小。
加密过程中,将加密的文本块分成两半。
使用子密钥对其中一半应用循环功能,
然后将输出与另一半进行“异或”运算;接着交换这两半。
循环往复。
DES使用16个循
环,但最后一个循环不交换。
攻击DES,一般只能使用穷举的密钥搜索,即重复尝试各种密钥直到有一个符合为
止。
如果DES使用56位的密钥,则可能的密钥数量是256个,穷举难度较大。
IBM曾对DES拥有几年的专利权,但在1983年到期。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。
加密算法E和解密算法D也都是公开的。
虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。
正是基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可在网络服务器中注册。
为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。
这就使加密的计算量很大。
为减少计算量,在传送信息时,常采用传统加密方法与公开密钥加密方法相结合的方式,即信息采用改进的DES或IDEA对话密钥加密,然后使用RSA密钥加密对话密钥和信息摘要。
对方收到信息后,用不同的密钥解密并可核对信息摘要。
2.问题分析
(1).对称密钥密码体系
对称密钥密码体系也叫密钥密码体系,它是指消息发送方和消息接收方必须使用相同的密钥,该密钥必须保密。
发送方用该密钥对待发消息进行加密,然后将消息传输至接收方,接收方再用相同的密钥对收到的消息进行解密。
这一过程可用数学形式来表示。
消息发送方使用的加密函数encrypt有两个参数:
密钥K和待加密消息M,加密后的消息为E,E可以表示为E=encrypt(K,M)消息接收方使用的解密函数decrypt把这一过程逆过来,就产生了原来的消息M=decrypt(K,E)=decrypt(K,encrypt(K,M))
(2).非对称密钥密码体系
非对称密钥密码体系又叫公钥密码体系,它使用两个密钥:
一个公共密钥PK和一个私有密钥SK。
这两个密钥在数学上是相关的,并且不能由公钥计算出对应的私钥,同样也不能由私钥计算出对应的公钥。
这种用两把密钥加密和解密的方法表示成如下数学形式。
假设M表示一条消息,pub—a表示用户a的公共密钥,prv—a表示用户a的私有密钥,那么:
M=decrypt(pub—a,encrypt(prv—a,M))
3.算法分析及流程图
4.实验原理
(1)利用java中的KeypairGenerator类创建公钥密钥对,工厂类KeypairGenerator的静态方法getInstance()可以获得KeypairGenerator类型对象。
(2)方法getInstance()的参数为字符串类型,指定加密算法为RSA。
(3)RSA算法是使用整数进行加密运算的,RSA的公钥中包含两个信息:
公钥对应的整数e和用于取模的整数n。
对于明文m计算密文的公式是memodn。
java中的BigInteger类中定义的modPow()方法可以计算memodn。
(4)RSA的私钥中包含两个信息:
私钥对应的整数d和用于取模的整数n。
计算明文的公式是:
Cemodn。
5.类图
四.数据测试及结果
1、利用DES算法生成对称密钥Key,运行程序后生成Key.dat文件
2、利用RSA算法生成公钥密钥对,将公钥存入A文件夹下,将私钥存入B文件夹下,运行程序后在A文件夹下生成Skey_RSA_pub.dat文件,在B文件夹下生成Skey_RSA_priv.dat文件:
3.利用RSA加密算法对对称密钥加密,将加密后文件保存为Enc_RSA.dat文件,运行程序后:
4、利用RSA解密算法对密文进行解密,将解密后的文件Key.dat写入B文件夹下,运行程序后B文件夹下生成Key.dat文件:
五.总结
通过本次实习,复习了DES和RSA的相关知识,通过使用DES算法和RSA算法实现密钥分发与通信过程,对密钥的分配过程有了一定的了解。
让我更加认识到了加密算法的复杂,也更加巩固了我们的java知识,理解了公钥密码算法,掌握了RSA密码算法加解密过程的实现,学习了java.security.*和java.crypto.*中相关类。
对于KeypairGenerator,KeyPair,PublicKey,PrivateKey等类有了进一步的了解,RSA算法是使用整数进行加密运算的,RSA的公钥中包含两个信息公钥对应的整数e和用于取模的整数n。
由于时间精力有限,本次实验还存在很多问题,在控制台进行明文的加密解密正常,图形界面的加密也正常,解密时调用Skey_RSA的解密方法时未能完成解密工作。
加密方法的参数密钥由KeypairGenerator的静态方法getInstance()可以获得KeypairGenerator类型对象,所以在界面使用文本框获得key值会造成初始化方法init()的publickey参数错误,于是设置成密钥由系统生成。
Ciphercipher=Cipher.getInstance("RSA");//Cipher负责完成加密或解密工作,基于RSA
cipher.init(Cipher.ENCRYPT_MODE,publicKey);//根据公钥,对Cipher对象进行初始化
对称密码一般要求:
1、加密解密用相同的密钥
2、收发双方必须共享密钥
安全性要求:
1、密钥必须保密
2、没有密钥,解密不可行
3、知道算法和若干密文不足以确定密钥
公钥密码一般要求:
1、加密解密算法相同,但使用不同的密钥
2、发送方拥有加密或解密密钥,而接收方拥有另一个密钥
安全性要求:
1、两个密钥之一必须保密
2、无解密密钥,解密不可行
3、知道算法和其中一个密钥以及若干密文不能确定另一个密钥
源程序
//生成对称密钥
packageSkey;
importjava.io.FileOutputStream;
importjava.io.ObjectOutputStream;
importjavax.crypto.KeyGenerator;
importjavax.crypto.SecretKey;
publicclassSkey_DES{
/**
*@paramargs
*/
//TODOAuto-generatedmethodstub
//对称密钥的生成,并通过对象序列化方式保存在文件中
publicstaticvoidmain(Stringargs[])throwsException
{
KeyGeneratorkg=KeyGenerator.getInstance("DESede");//创建密钥生成器
kg.init(168);//初始化密钥生成器
SecretKeyk=kg.generateKey();//生成密钥
//通过对象序列化方式将密钥保存在文件中
FileOutputStreamf1=newFileOutputStream("A/Key.dat");
ObjectOutputStreamb1=newObjectOutputStream(f1);
b1.writeObject(k);
}
}
//生成对称密钥对
packageRSA;
importjava.io.*;
importjava.security.*;
importjava.security.interfaces.RSAPrivateKey;
importjava.security.interfaces.RSAPublicKey;
importjavax.crypto.Cipher;
publicclassSkey_RSA{
//KeyGenerator提供对称密钥生成器的功能,支持各种算法
publicKeyPairGeneratorkeyPairGen;
//SecretKey负责保存对称密钥
KeyPairkeyPair;
RSAPrivateKeyprivateKey;
RSAPublicKeypublicKey;
//Cipher负责完成加密或解密工作
privateCipherc;
//该字节数组负责保存加密的结果
privatebyte[]cipherByte;
//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
/**
*@paramargs
*/
Skey_RSA(){
//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGeneratorkeyPairGen=null;
try{
keyPairGen=KeyPairGenerator.getInstance("RSA");
}catch(NoSuchAlgorithmExceptione){
//TODO自动生成的catch块
e.printStackTrace();
}
//初始化密钥对生成器,密钥大小为1024位
keyPairGen.initialize(1024);
//生成一个密钥对,保存在keyPair中
KeyPairkeyPair=keyPairGen.generateKeyPair();
//得到私钥
RSAPrivateKeyprivateKey=(RSAPrivateKey)keyPair.getPrivate();
//得到公钥
RSAPublicKeypublicKey=(RSAPublicKey)keyPair.getPublic();
}
publicRSAPrivateKeygetPrivateKey(){
returnprivateKey;
}
publicvoidsetPrivateKey(RSAPrivateKeyprivateKey){
this.privateKey=privateKey;
}
publicRSAPublicKeygetPublicKey(){
returnpublicKey;
}
publicvoidsetPublicKey(RSAPublicKeypublicKey){
this.publicKey=publicKey;
}
publicbyte[]encrypt(RSAPublicKeypublicKey,byte[]srcBytes){
if(publicKey!
=null){
try{
//Cipher负责完成加密或解密工作,基于RSA
Ciphercipher=Cipher.getInstance("RSA");
//根据公钥,对Cipher对象进行初始化
cipher.init(Cipher.ENCRYPT_MODE,publicKey);
//加密,结果保存进resultBytes
byte[]resultBytes=cipher.doFinal(srcBytes);
returnresultBytes;
}catch(Exceptione){
e.printStackTrace();
}
}
returnnull;
}
publicbyte[]decrypt(RSAPrivateKeyprivateKey,byte[]encBytes){
if(privateKey!
=null){
try{
Ciphercipher=Cipher.getInstance("RSA");
//根据私钥,对Cipher对象进行初始化
cipher.init(Cipher.DECRYPT_MODE,privateKey);
//解密,结果保存进resultBytes
byte[]decBytes=cipher.doFinal(encBytes);
returndecBytes;
}catch(Exceptione)
{
e.printStackTrace();
}
}
returnnull;
}
publicstaticvoidmain(String[]args)throwsException{
//密钥对生成器KeyPairGenerator工厂,非对称加密算法:
RSA,DSA
KeyPairGeneratorkpg=KeyPairGenerator.getInstance("RSA");
//制定密钥长度
kpg.initialize(1024);
//生成密钥对
KeyPairkp=kpg.genKeyPair();
PublicKeypbkey=kp.getPublic();
PrivateKeyprkey=kp.getPrivate();
FileOutputStreamf1=newFileOutputStream("A/Skey_RSA_pub.dat");
ObjectOutputStreamb1=newObjectOutputStream(f1);
b1.writeObject(pbkey);
FileOutputStreamf2=newFileOutputStream("B/Skey_RSA_priv.dat");
ObjectOutputStreamb2=newObjectOutputStream(f2);
b2.writeObject(prkey);
Skey_RSArsa=newSkey_RSA();
Stringmsg="rsa_安全编程技术";
System.out.println("明文是:
"+msg);
//KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGeneratorkeyPairGen=KeyPairGenerator.getInstance("RSA");
//初始化密钥对生成器,密钥大小为1024位
keyPairGen.initialize(1024);
//生成一个密钥对,保存在keyPair中
KeyPairkeyPair=keyPairGen.generateKeyPair();
//得到私钥
RSAPrivateKeyprivateKey=(RSAPrivateKey)keyPair.getPrivate();
//得到公钥
RSAPublicKeypublicKey=(RSAPublicKey)keyPair.getPublic();
//用公钥加密
byte[]srcBytes=msg.getBytes();
byte[]resultBytes=rsa.encrypt(publicKey,srcBytes);
Stringresult=newString(resultBytes);
System.out.println("用公钥加密后密文是:
"+result);
//用私钥解密
byte[]decBytes=rsa.decrypt(privateKey,resultBytes);
Stringdec=newString(decBytes);
System.out.println("用私钥解密后结果是:
"+dec);
}
}
//公钥加密
packageRSA;
importjava.security.interfaces.RSAPublicKey;
importjava.math.*;
importjava.io.*;
publicclassEnc_RSA{
publicstaticvoidmain(String[]args)throwsException{
BufferedReaderin=newBufferedReader(newInputStreamReader(newFileInputStream("A/Key.dat")));
Strings=in.readLine();
FileInputStreamf=newFileInputStream("A/Skey_RSA_pub.dat");
ObjectInputStreamb=newObjectInputStream(f);
//公钥转换为RSA公钥
RSAPublicKeypbk=(RSAPublicKey)b.readObject();
//获取公钥参数:
公钥对应的整数e,用于取模的整数n
BigIntegere=pbk.getPublicExponent();
BigIntegern=pbk.getModulus();
System.out.println("e="+e);
System.out.println("n="+n);
byteptext[]=s.getBytes("UTF8");
BigIntegerm=newBigInteger(ptext);
BigIntegerc=m.modPow(e,n);
System.out.println("c="+c);
Stringcs=c.toString();
BufferedWriterout=
newBufferedWriter(newOutputStreamWriter(
newFileOutputStream("Enc_RSA.dat")));
out.write(cs,0,cs.length());
out.close();
}
}
//私钥解密
packageRSA;
importjava.security.interfaces.*;
importjava.math.*;
importjava.io.*;
publicclassDec_RSA{
publicstaticvoidmain(String[]args)throwsException{
BufferedReaderin=newBufferedReader(
newInputStreamReader(
newFileInputStream("Enc_RSA.dat")));
Stringctext=in.readLine();
BigIntegerc=newBigInteger(ctext);
FileInputStreamf=newFileInputStream("B/Skey_RSA_priv.dat");
ObjectInputStreamb=newObjectInputStream(f);
RSAPrivateKeyprk=(RSAPrivateKey)b.readObject();
BigIntegerd=prk.getPrivateExponent();
BigIntegern=prk.getModulus();
System.out.println("d="+d);
System.out.println("n="+n);
BigIntegerm=c.modPow(d,n);
System.out.println("m="+m);
byte[]mt=m.toByteArray();
System.out.println("PlainTextis");
for(inti=0;iSystem.out.print((char)mt[i]);
FileOutputStreamf1=newFileOutputStream("B/Key.dat");
ObjectOutputStreamb1=newObjectOutputStream(f1);
b1.writeObject(m);
}
}
}
//图形界面
packageDec;
/*
*Window.java
*
*Createdon__DATE__,__TIME__
*/
importjava.io.IOException;
importjava.security.interfaces.RSAPublicKey;
importjava.util.Scanner;
/**
*
*@author__USER__
*/
publicclassWindowextendsjavax.swing.JFrame{
/**CreatesnewformWindow*/
publi