Java程序设计基础项目总结报告
20135313吴子怡
一、项目内容
运用所学Java知识,不调用Java类库,实现密码学相关算法的设计,并完成TDD测试,设计运行界面。
二、具体任务
1、要求实现的密码算法包括:对称密码算法,非对称密码算法,消息摘要算法。
2、要求完成对每个算法中的public类进行TDD测试,测试代码尽可能多,并且应尽可能涵盖特殊符号、数字、字母等输入字符。
3、设计每个密码算法的GUI界面,提供输入输出区域供使用者输入、查看。
三、计划明细
周数 |
进度安排 |
备注 |
Week5 |
查询项目包含的每个小块算法的资料和实现需要的方法以及基础知识 |
袁征老师所教的现代密码学尚起步,对密码学知识了解不多,因此前期查询自学工作任务较重。 |
Week6 |
阅读完《图解密码技术》的相关内容。 |
学会DES、AES、RSA、ElGamal、SHA-1、MD5的理论。 |
Week7 |
阅读《Java加密与解密的艺术》内的相关内容,了解Java JCA、JCE、JSSE、JAAS。运行调试查询到的代码,可以下载,不用输入,能够运行。 |
了解到程序中对算法代码的调用和输入输出格式等,对自己设计算法时的一些基本操作有了一定了解。 |
Week8 |
预习现代密码学中的算法:对称算法、非对称算法、摘要算法、身份认证这四项。 |
之前通过《图解密码技术》学会了各算法的基本思路,本周主要是通过课内教材对具体数学基础和每个模块的计算进行详细学习。 |
Week9 |
对照理论知识和编程资料,设计算法的实现模块。 |
无 |
Week10 |
实现对称算法2个。 |
即不调类库的DES、AES算法。 |
Week11 |
实现非对称算法2个。 |
即不调类库的RSA、ElGamal算法。 |
Week12 |
实现摘要算法2个。并对所实现的6个密码算法进行修改,通过查询调类库实现的Java已经封装好的密码算法、网上程序员编写的代码,借鉴高级语句,完善代码。 |
即不调类库的SHA-1、MD5算法。并借鉴网上的牛人分享的开源代码,将之前写的基础的单个隔离的类修改为包含继承、接口的代码块。 |
Week13 |
使用TDD单元测试对密码算法进行测试,并对不通过测试的部分进行修改。 |
对每个public方法都进行TDD测试。 |
Week14 |
学习GUI,为所实现的密码算法设计界面。 |
查找GUI的编程实例,在主函数中重点使用了包含输入、输出、选择对话框的语句,简单设计出能够提供给用户可视化界面的代码。 |
Week15 |
将TDD测试代码做成TDDsuit。将密码学算法代码、TDD测试代码、带GUI界面的算法主函数分别打成jar包。撰写期末项目总结报告。 |
无 |
四、设计思路
1、项目设计初期,先通过《现代密码学》(课内同步教材)、《图解密码技术》(课外辅助学习教材)理解选择设计的密码算法的思路、计算过程、具体步骤、需要用到的数学理论。
2、根据已掌握的密码学知识,选择具体算法,按照计划安排实现。其中包括:AES、DES、RSA、ElGamal、MD5、SHA-1六个密码学算法。其中,ElGamal、RSA算法中包含其实现数字签名(属于自己扩充拓展练习的算法)的方法。
3、在编写程序的时候养成对方法进行注释的习惯,便于修改代码时的清晰查找以及算法实现后要对外公开供用户使用时形成帮助文档。
4、设计过程中,将一些不需要对外公开的方法或变量设为private,如:,并引入继承、接口等用于降低算法耦合度,便于后期优化修改,如:
5、设计中,偶尔尝试使用单例设计模式,但由于对Java设计不太熟练,应用不太顺手。
6、设计算法时,根据不同密码算法中使用到的数学知识,必须到在线API中查找相关的类和接口,选择出能够进行模幂运算或求欧拉函数值、生成随机素数等功能的类来帮助我编写算法。如:
通过查找API,得知所有操作中,都以二进制补码形式表示 BigInteger(如 Java 的基本整数类型)。BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外,BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
7、在写测试代码时,适逢Java课程实验二正在进行,刚好有机会入门学习TDD测试,个人又上网下载了pdf资料(讲述Junit单元测试的相关操作,详见报告参考文献),选择使用assertEqual断言式测试语句来测试代码中公开的方法。这些待测的方法大多数是加密方法和解密方法。因此只需在网站上进行在线加解密,生成应得的加解密结果,再与自己编写的加解密方法加解密相同明密文的结果进行比较,即可获得TDD测试结果。
8、由于Eclipse编码及Windows系统编码的内部问题,有时需要对package的编码方式进行修改,但是查询了网上的资料后发现有的地方对中文的加解密仍然存在问题。
即TDD单元测试出现red bar,因此尚待深入学习优化。
9、在写GUI界面时,由于加解密算法不存在太过于复杂的界面设计,因此只需要引入选择对话框、输入输出显示对话框等即可。自学起来较为简单。仍在尝试着将所有密码算法综合在一起编写带GUI的主函数,设计出多选择、简洁明了的Java加解密工程的界面。
五、实现过程
1、DES
(1)包含步骤:
给定64bit的明文M,通过一个固定的初始置换IP来排列得到M0。
进行16轮相同的迭代运算,这些运算被称为轮函数f。
对比特串R16L16使用逆置换IP-1得到密文C。
(2)方法列表:
其中包含有许多私有的方法用于进行加解密中很多置换、移位的计算以及数制的转换。
而公开的方法只有加密(encrypt)、解密(dsencrypt)、获取密钥(setKey),用于供给用户使用。
2、AES
(1)算法步骤
SubBytes()、ShiftRows()、MixColums()、AddRoundKey()四个方法。
(2)方法列表
其中包含了AES算法中的四个步骤,分别对应: subbyte、 shift、mix、add和其他的移位、S盒、数制格式化等私有方法。对外公开的仍然只有文本加解密两个方法。
3、RSA
(1)算法步骤
找出两个相异的大素数p,q,计算:n=pq,φ(n)=(p-1)(q-1), n公开,φ(n)保密
随机生成一个整数e,要求满足:1<e<φ(n)-1,(e,φ(n))=1
应用Enclid算法求出d:
公开密钥k’=(e,n),秘密密钥k”=d,(e、d分别称为加密指数与解密指数)
(2)方法列表
所有的计算模幂运算均封装在calculateD()中,加解密方法对外公开。
4、ElGamal
(1)算法步骤
加密算法:设明文为m,0≤m≤p,随机选择一个正整数k,gcd(k,p-1)=1,计算
y1(密文)=gk mod p
y2(密文)=mbk mod p
解密算法: m(明文)=y2 /y1a modp=mbk /gka=mgka /gka =m
(2)方法列表
5、MD5
(1)算法步骤
a.填充
在MD5算法中,首先需要对信息进行填充,使其位长对512求余的结果等于448,并且填充必须进行,即使其位长对512求余的结果等于448。
b. 初始化变量
初始的128位值为初试链接变量,这些参数用于第一轮的运算,以大端字节序来表示。
c. 处理分组数据
第一分组需要将上面四个链接变量复制到另外四个变量中:A到a,B到b,C到c,D到d。从第二分组开始的变量为上一分组的运算结果,即A = a, B = b, C = c, D = d。
进行四轮主循环,再将所得结果向左环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。
d.输出
(2)方法列表
其中的calcMD5()就是求消息摘要的算法。
6、SHA-1
(1)算法步骤
步骤一:附加填充比特
步骤二:附加长度值
步骤三:初始化MD缓存
步骤四:处理512比特(16个字)报文分组序列,算法的核心是一个包含4个“循环”的模块,每循环由20个处理步骤组成
步骤五:输出
(2)方法列表
其中包含消息摘要的一些非线性函数、数组格式化、数制转换等私有方法外,对外公开的getDigestOfBytes(byte[])就是求消息摘要的方法。
六、主函数包
七、测试代码包
八、帮助文档
九、心得体会
在Java程序设计基础课程中参加了项目小组,我除了跟随一般课堂中同步的毕向东老师Java视频教学以外,更多的是自学和应用。我所做的项目主要是实现与密码学有关的加解密算法和求消息摘要的算法。因为密码学算法对于程序运行结果较为直观,正确与否更加明显。而且我个人对于密码学较有兴趣,因此应用Java编写密码学程序动力很大。但是在此过程中也遇到了很多问题。比如在加解密过程中,结果输出并不是所期待的字节数组。再比如算法对于中文的加解密仍然存在问题、对于继承、单例等应用不熟练。
同时我也从中学到了更多的技巧,比如运用娄老师所介绍的TDD单元测试进行调试代码,对GUI界面的设计使用、代码模块化的思想、对面向对象等的了解更为深入。因此,我认为在参与项目的过程中虽然压力更大些,对于密码学算法、Java的学习进度和强度的要求更为高些,但终究是受益匪浅的。
十、展望
1、将各种算法集成,放在同一个GUI界面中。
2、将算法的耦合度降低,多使用一些继承、接口、单例的设计。
十一、参考文献
1、51CTO下载-单元测试之道Java版:使用JUnit.pdf
2、Java加密与解密的艺术(第二版) 机械工业出版社 梁栋 著
3、《现代密码学》(课内教材)、袁征老师教学PPT
4、《图解密码技术》