西北农林科技大学信息安全实验三.docx
《西北农林科技大学信息安全实验三.docx》由会员分享,可在线阅读,更多相关《西北农林科技大学信息安全实验三.docx(12页珍藏版)》请在冰豆网上搜索。
![西北农林科技大学信息安全实验三.docx](https://file1.bdocx.com/fileroot1/2023-1/24/cf1ad20d-b7ec-44d4-9509-046448af49c9/cf1ad20d-b7ec-44d4-9509-046448af49c91.gif)
西北农林科技大学信息安全实验三
信息工程学院
信息安全原理及应用实验报告
实验三基于RSA的公钥加密
班级:
计算机XX
学号:
XXXXXXX
姓名:
XXXXX
指导老师:
XXXXX
一、实验目的
1.理解公钥密码算法,熟悉常用密码算法:
RSA、椭圆曲线密码体制;
2.理以RSA加密算法为例,掌握公钥密码算法加解密过程的实现。
二、实习内容
1.[基本要求]
以RSA为例,利用java中的相关类实现对指定字符串的加解密。
2.[实现提示]
(1)可以利用java中的KeypairGenerator类创建公钥密钥对,工厂类KeypairGenerator的静态方法getInstance()可以获得KeypairGenerator类型对象。
(2)方法getInstance()的参数为字符串类型,指定加密算法的名称如:
RSA。
(3)利用工厂类Cipher的对象创建密码器。
同样的,getInstance()的参数为字符串类型,指定加密算法的名称。
(4)JSDK1.2中只是实现了RSA密钥创建,没有实现RSA算法,因此需要安装其他加密软件提供者的软件包,才能直接使用Cipher类执行加解密。
(5)RSA算法是使用整数进行加密运算的,RSA的公钥中包含两个信息:
公钥对应的整数e和用于取模的整数n。
对于明文m计算密文的公式是memodn。
java中的BigInteger类中定义的modPow()方法可以计算memodn。
(6)RSA的私钥中包含两个信息:
私钥对应的整数d和用于取模的整数n。
计算明文的公式是:
Cemodn。
三、测试数据和预期结果
1.测试数据:
明文:
HelloUserB!
e=65537
n=901555080980479054261289117105730288186307404340275543727489749127530630
35513699150577829243362139796437472252024998435422860371393397734043000574146477685433337274922097418662342571073587072429662034780459855457910319275705853063428389277947471782777251917943575355289890002087854701934153204294157020784747
2.预测结果:
m=112538405354885716280897067137139232297231576752176647999066079730260155
78815420520321236527400219496525363940515236822159671810260812132516608590481840367585218934895815814333869183138495764680612749825153910274532648748320204216833296167081023385937007859365228073517478723018190901085831856225136435773586
d=252072803208665306472433309151248940304345589165375422482910755191920156
10460549357388774937140361164379209325207227540636411392731016373630223271139357260160898347846618224557735499399971970242992916184496303669743854746835920016717183151204857451734643665107085662188516607520806177363202710556814157473153
n=901555080980479054261289117105730288186307404340275543727489749127530630
35513699150577829243362139796437472252024998435422860371393397734043000574146477685433337274922097418662342571073587072429662034780459855457910319275705853063428389277947471782777251917943575355289890002087854701934153204294157020784747
解密:
HelloUserB!
四、算法分析和流程图
1、RSA算法的加密解密
基础过程分为三个:
生成RSA 公钥和私钥、使用公钥加密、使用密钥解密。
1.1生成RSA 公钥和私钥
Java的KeyPairGenerator类提供了一些方法来创建密钥对以便用于非对称加密,密钥对创建好后封装在KeyPair类型的对象中,在KeyPair类中提供了获取公钥和私钥的方法。
具体步骤如下:
1.1.1创建密钥对生成器
KeyPairGeneratorkpg=KeyPairGenerator.getInstance("RSA");
1.1.2初始化密钥生成器
kpg.initialize(1024);
对于密钥长度。
对于RSA算法,这里指定的其实是RSA算法中所用的模的位数。
可以在512到2048之间。
1.1.3生成密钥对
KeyPairkp=kpg.genKeyPair();
一对公钥和私钥的信息。
1.1.4获取公钥和私钥
PublicKeypbkey=kp.getPublic();
PrivateKeyprkey=kp.getPrivate();
1.2使用公钥加密
RSA算法是使用整数进行加密运算的,在RSA公钥中包含了两个信息:
公钥对应的整数e和
用于取模的整数n。
对于明文数字m,计算密文的公式是:
。
因此,编程步骤如下:
1.2.1获取公钥
FileInputStreamf=newFileInputStream("Skey_RSA_pub.dat");
ObjectInputStreamb=newObjectInputStream(f);
RSAPublicKeypbk=(RSAPublicKey)b.readObject();
1.2.2获取公钥的参数(e,n)
BigIntegere=pbk.getPublicExponent();
BigIntegern=pbk.getModulus();
分别获得公始中e和n的值。
由于密钥很长,因此对应的整数值非常大,无法使用一般的整型来存储,Java中定义了BigInteger类来存储这类很大的整数并可进行各种运算。
1.2.3获取明文整数(m)
Strings="HelloWorld!
";
byteptext[]=s.getBytes("UTF8");
BigIntegerm=newBigInteger(ptext);
分析:
明文是一个字符串,为了用整数表达这个字符串,先使用字符串的getBytes()方法将其转换为byte类型数组,它其实是字符串中各个字符的二进制表达方式,这一串二进制数转换为一个整数将非常大,因此仍旧使用BigInteger类将这个二进制串转换为整型。
1.2.4执行计算
BigIntegerc=m.modPow(e,n);
执行这个计算。
底数m执行这个方法,方法modPow()的第一个参数即指数e,第二个参数即模n。
方法返回的结果即公式
的计算结果,即密文。
1.3使用密钥解密
RSA算法的解密和加密类似,在RSA私钥中包含了两个信息:
私钥对应的整数d和用于取模的整数n。
其中的n和加密时的n完全相同。
对于密文数字c,计算明文的公式是:
,之所以加密时由公式
得到的密文c通过这个公式计算一下就可以反过来得到原来的明文m,有其本身的数学规律决定。
1.3.1读取密文
BufferedReaderin=newBufferedReader(newInputStreamReader(
newFileInputStream("Enc_RSA.dat")));
Stringctext=in.readLine();
BigIntegerc=newBigInteger(ctext);
由于这一行字符串表示的是一个很大的整型数,因此使用BigInteger类来表示这个整型数。
1.3.2获取私钥
FileInputStreamf=newFileInputStream("Skey_RSA_priv.dat");
ObjectInputStreamb=newObjectInputStream(f);
RSAPrivateKeyprk=(RSAPrivateKey)b.readObject();
用的是RSA算法,因此从文件读取公钥对象后强制转换为RSAPrivateKey类型,以便后
面读取RSA算法所需要的参数。
1.3.3获取私钥的参数(d,n)
BigIntegerd=prk.getPrivateExponent();
BigIntegern=prk.getModulus();
1.3.4执行计算
BigIntegerm=c.modPow(d,n);
1.3.5计算明文整型数对应的字符串
byte[]mt=m.toByteArray();
for(inti=0;iSystem.out.print((char)mt[i]);
}
RSA算法解密的结果m是一个很大的整数,为了计算出其对应的字符串的值,先使用BigInteger类的toByteArray()方法得到代表该整型数的字节数组,然后将数组中每个元素转换为字符,组成字符串。
2、程序设计
程序模拟A、B两用户,实现他们之间的通讯。
通讯方法:
A用B的公钥将明文加密后,将密文发送给B,B用自己的密钥解密可得到明文;同理B用A的公钥加密后,将密文发送给A,A用自己的密钥解密可得到明文。
A、B的公钥以二进制文件的形式存储,方便读写,A、B的私钥封装在UserA、UserB类对象中。
UserA向UserB单项的传输信息的过程
UserB向UserA传输信息的过程与此相同
3、程序结构
程序包括4个大类
3.1MainClass.java
成员函数:
publicstaticvoidmain(String[]args)//主函数
3.2Frame.java
成员变量:
JLabelA_label;
JLabelB_label;
JLabelA_pt;
JLabelB_pt;
JLabelA_ct;
JLabelB_ct;
JLabelA_receive;
JLabelB_receive;
JTextAreaAp_tArea;
JTextAreaAc_tArea;
JTextAreaBp_tArea;
JTextAreaBc_tArea;
JTextAreaAr_tArea;
JTextAreaBr_tArea;
JButtonbutton_CA;
JButtonbutton_CB;
JButtonA_encrypt;
JButtonB_encrypt;
JButtonA_send;
JButtonB_send;
JButtonA_decrypt;
JButtonB_decrypt;
UserAUserA;
UserBUserB;
成员函数:
publicFrame(Stringst)//初始化函数
publicvoidactionPerformed(ActionEvente)//事件监听函数
3.3RSA.java
成员变量:
privatePublicKeypbkey//公钥
privatePrivateKeyprkey//私钥
成员函数:
publicRSA()初始化函数
publicvoidwriteToFile(StringfileName)//将密钥写入一二进制文件
publicRSAPrivateKeychangeToRSAPrivateKey()//将PrivateKey类的私钥转成
RSAPrivateKey类的私钥
3.4UserA.java(UserB.java与UserA.java类似)
成员变量:
privateRSARSA_A
privateRSAPublicKeyrsa_a_pbkey//公钥
privateRSAPrivateKeyrsa_a_prkey//私钥
成员函数:
publicUserA()//初始化函数
publicStringencrypt(Stringtext)//加密函数
publicStringdecrypt(Stringtext)//解密函数
UML类图:
五、运行结果
1.运行程序
2.分别点击UserA、UserB的“生成密钥对”按钮,控制台会显示生成成功,在工程文件夹下生成了两个二进制文件。
3.在UserA的明文框里输入“HelloUserB!
”,后点击加密,密文会出现在密文框中
4.点击“发送”按钮,UserA将密文发送给UserB,UserB接收到后将会在接收框内显示密文,点击“解密”按钮方可加密获得明文并在接收框内显示。
5.UserB发信息给UserA的操作过程与上述一致
六、小结
本次实验主要是理解公钥密码算法,熟悉常用密码算法理解了古典加密技术中的替换技术、置换技术。
理以RSA加密算法,以RSA加密算法为例,掌握公钥密码算法加解密过程的实现。
在实习过程中主要的问题是,密钥的管理上,一开始将公钥、私钥一同封装在了对象中,发现在公钥的使用上,不仅麻烦,而且很不合理。
后来将公钥写入二进制文件中,这样访问起来也比较方便,同时设计也更加合理,符合实际情况。
附录(代码)