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、《圖解密碼技術》