指導教師:婁嘉鵬html
題目要求:基於Arm實驗箱的國密算法應用
三種平臺:
Z32
ARM32+Linux
STM32
內容:
SM1, SM2,SM3算法測試
算法應用:混合密碼系統ios
運行老師給的範例代碼,熟悉開發軟件和開發板的使用;收集資料簡單瞭解Z32,ARM的基本概念,而後實現ARM與Ubuntu映射文件。成功編譯並運行代碼。c++
首先設計一個客戶端與服務器可以互相接收,發送信息;再設計一個串口程序,能夠經過超級終端打開ARM與Z32的串口,使ARM可以調用Z32中的程序進行加解密算法
國密SM2是非對稱密碼算法,是基於ECC算法的非對稱算法。SM2算法就是ECC橢圓曲線密碼機制,但在簽名、密鑰交換方面不一樣於ECDSA、ECDH等國際標準,而是採起了更爲安全的機制。另外,SM2推薦了一條256位的曲線做爲標準曲線。
國密SM2算法標準包括4個部分,第1部分爲總則,主要介紹了ECC基本的算法描述,包括素數域和二元擴域兩種算法描述,第2部分爲數字簽名算法,這個算法不一樣於ECDSA算法,其計算量大,也比ECDSA複雜些,也許這樣會更安全吧,第3部分爲密鑰交換協議,與ECDH功能相同,但複雜性高,計算量加大,第4部分爲公鑰加密算法,使用ECC公鑰進行加密和ECC私鑰進行加密算法,其實現上是在ECDH上分散出流密鑰,以後與明文或者是密文進行異或運算,並無採用第3部分的密鑰交換協議產生的密鑰。對於SM2算法的整體感受,應該是國家發明,其計算上比國際上公佈的ECC算法複雜,相對來講算法速度可能慢,但多是更安全一點。
SM2標準還公佈了一條建議的256位的ECC曲線,但沒有在國際上被公認。SM2算法是好,但要使用,又有不少障礙,就是統一的國際標識與互認,如算法沒有OID標識,曲線也沒有公認OID標識,這在通用上就大打折扣了,這一點須要考慮的數組
實驗過程及結果:
一、打開「Z32開發指南\實驗1-LED閃爍」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。安全
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。服務器
當左邊框出現「1設備已鏈接」,設備選擇中顯示芯片型號,此時就能夠下載程序了。函數
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗1的程序就下載進Z32的實驗板上了。
實驗現象:
實驗1的內容是對LED燈的操做,咱們關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:Z32核心板上L2燈開始閃爍。工具
實驗過程及結果:
一、打開「Z32開發指南\實驗2-UART發送與中斷接收」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。測試
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗2的程序就下載進Z32的實驗板上了。
實驗2使用串口調試助手(sscom)來觀察串口通訊收發的數據。
咱們用9針串口線將Z32模塊的串口與電腦USB接口鏈接。
首先在電腦上打開串口助手,選擇對應的串口號,設置波特率爲115200,偶校驗(Even),選中「發送新行」,而後打開串口。
關閉Z32電源開關,再打開,程序自動運行,能夠在串口調試助手看到以下實驗現象:顯示「A Welcome to Z32HUA! 1234567890 0xAA」,證實PC機串口已經接收到Z32串口發送來的信息。
咱們在串口調試助手的字符串輸入框輸入字符串「abcdefgh」,而後點擊發送按鈕。
這時,能夠看到串口調試助手接收到咱們發送輸入的字符串「abcdefgh」,並顯示在串口助手上。
實驗過程及結果:
一、打開「Z32開發指南\實驗3-12864液晶屏串行顯示」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。
當左邊框出現「1設備已鏈接」,設備選擇中顯示芯片型號,此時就能夠下載程序了。
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗3的程序就下載進Z32的實驗板上了。
實驗3的內容是LCD12864液晶屏的顯示操做。
關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:屏幕上依次顯示如下字符:
「歡迎使用Z32HUA!
LCD12864液晶測試
1.2.3.4.5.6.7.8.
A.B.C.D.E.F.G.H.」
其中行與行之間顯示的間隔時間約爲1.8s,四行字符所有顯示完成後清屏幕,從新循環顯示。
實驗過程及結果:
一、打開「Z32開發指南\實驗4-GPIO0按鍵中斷」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。
當左邊框出現「1設備已鏈接」,設備選擇中顯示芯片型號,此時就能夠下載程序了。
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗4的程序就下載進Z32的實驗板上了。
實驗4的內容是按鍵中斷,12864顯示屏顯示字符。
關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:12864屏幕第一行顯示:「請按reboot按鍵:」
依次按下按鍵10次後,屏幕第二行顯示0~9的數字。
實驗過程及結果:
一、打開「Z32開發指南\實驗5-矩陣鍵盤」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。
當左邊框出現「1設備已鏈接」,設備選擇中顯示芯片型號,此時就能夠下載程序了。
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗5的程序就下載進Z32的實驗板上了。
實驗5的內容是讀矩陣鍵盤鍵值並顯示。
關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:12864屏幕第一行顯示字符串
按下矩陣鍵盤上「A」鍵,屏幕第二行顯示「A」。
按下「A」鍵顯示圖
實驗過程及結果:
一、打開「Z32開發指南\實驗6-TIMER定時器」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
Z32工程編譯圖
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗6的程序就下載進Z32的實驗板上了。
實驗6的內容是定時器溢出中斷,控制LED燈以0.5Hz頻率亮滅,並將0~9秒循環計數顯示在12864顯示屏上。
關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:Z32核心板上的燈L2以0.5Hz頻率閃爍,12864屏幕上顯示「定時器測試:」,第二行循環顯示從0到9的秒計數值。
每隔1秒燈L2亮或滅一次,當計數值爲偶數時,燈L2亮,計數值爲奇數時,燈L2滅。
實驗過程及結果:
一、打開「Z32開發指南\實驗7-SLE4428邏輯加密卡」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。
當左邊框出現「1設備已鏈接」,設備選擇中顯示芯片型號,此時就能夠下載程序了。
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗7的程序就下載進Z32的實驗板上了。
實驗7的內容是SLE4428邏輯加密卡實驗,按照程序提示,插入SLE4428邏輯加密卡,A段程序顯示用戶代碼並進行密碼校驗,B段程序讀取卡片存儲的金額信息並修改金額。
關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:顯示屏第一行顯示「SLE4428實驗!」,第二行顯示「請插入IC卡...」。
插入SLE4428 IC卡,顯示屏第三行顯示:「用戶代碼爲:」,第四行顯示用戶代碼「D27600000400」。
若插入了正確的卡片,顯示出用戶代碼,再按下矩陣鍵盤的「A」鍵,屏幕第一行顯示提示「按-A鍵校驗密碼」並在第二行顯示兩個字節的校驗密碼「校驗0xFF,0xFF」。
按下矩陣鍵盤的「A」鍵,屏幕第三行顯示「校驗成功」,第四行顯示校驗剩餘機會「剩餘機會:8次」。
再按下矩陣鍵盤的「A」鍵,則屏幕第一行顯示卡內金額數「金額:100」,第二行提示「輸入金額,A鍵修改」。
在矩陣鍵盤上輸入三位修改的金額數200,按下矩陣鍵盤的「A」鍵確認。
確認後,金額更新,屏幕上顯示更改後的卡內金額「金額200」,第四行繼續提示「輸入金額,A鍵修改」,能夠再次進行更改。
修改完金額後,就能夠拔出IC卡。
實驗過程及結果:
一、打開「Z32開發指南\實驗8-SM1」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
Z32工程編譯圖
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。
當左邊框出現「1設備已鏈接」,設備選擇中顯示芯片型號,此時就能夠下載程序了。
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗8的程序就下載進Z32的實驗板上了。
實驗8的內容是SM1加解密實驗,待加密的原始數據以及加密祕鑰已經內置到程序中,修改UINT8 jiamiqian[16]數組便可更換待加密數據,修改jiamimiyue[16]數組和cuowumiyue[16]便可修改正確和錯誤的加密密鑰。本實驗一樣使用SLE4428 IC卡做爲加解密介質,按照程序提示,插入SLE4428邏輯加密卡,A段程序顯示用戶代碼並進行密碼校驗,B段程序進行加密/解密選擇,加密程序段進行SM1加密並將加密先後數據經過串口發送至PC機,解密程序段進行SM1解密並將解密先後數據經過串口發送至PC機。
咱們用9針串口線將Z32模塊的串口與電腦USB接口鏈接。
首先在電腦上打開串口助手,選擇對應的串口號,設置波特率爲115200,偶校驗(Even),而後打開串口。
關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:顯示屏顯示「SLE4428實驗!請插入IC卡...」。
插入SLE4428 IC卡,顯示屏第三行顯示:「用戶代碼爲:」,第四行顯示用戶代碼「D27600000400」。
若插入了正確的卡片,顯示出用戶代碼,再按下矩陣鍵盤的「A」鍵,屏幕第一行顯示提示「按-A鍵校驗密碼」並在第二行顯示兩個字節的校驗密碼「校驗0xFF,0xFF」。
按下矩陣鍵盤的「A」鍵,屏幕第三行顯示「校驗成功」,第四行顯示校驗剩餘機會「剩餘機會:8次」。
再按下矩陣鍵盤的「A」鍵,則屏幕第一行顯示「加密解密實驗」,第2、三行分別顯示選項「1.加密」,「2.解密」。
首先進行加密實驗。按「1」鍵選擇加密,屏幕第一行顯示「觀看串口調試助手」,第二行顯示「A鍵確認加密」。此時,串口調試助手顯示原始數據和加密密鑰。
按下「A」鍵確認加密後,屏幕第三行顯示「加密完成」,第四行顯示提示「A鍵存入IC卡」。串口調試助手顯示加密後的數據。
按「A」鍵,將加密數據存入IC卡,此時串口顯示「已將數據寫入IC卡」。屏幕回到加密解密實驗選擇菜單。
下面進行解密實驗。按「2」鍵選擇解密實驗後屏幕顯示「觀看串口調試助手 A鍵讀取IC卡數據」。
按「A」鍵後,此時屏幕顯示「讀取成功 選擇密鑰解密:1.正確密鑰 2.錯誤密鑰」。串口顯示「讀取的數據:爲:0x7E 0xDC 0xA3 0x7B 0xBA 0x53 0x84 0xAC 0x0B 0x75 0x50 0x45 0x2E 0xEC 0x4F 0x4F」。
按「1」鍵選擇正確的密鑰後,屏幕提示「A鍵確認解密」,此時串口顯示「將使用如下密鑰進行解密:0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F」。
按「A」 鍵確認解密後,屏幕提示「解密完成 A鍵返回」,此時串口顯示「解密後的數據爲:0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F」。
按「A」鍵返回加/解密選擇菜單。
若是使用錯誤祕鑰進行解密,解密後將不能獲得原始數據,在加/解密選擇菜單中按「2」進行解密實驗,用錯誤的祕鑰解密。屏幕提示「觀看串口調試助手 A鍵讀取IC卡數據」。
按「A」鍵後,此時屏幕顯示「讀取成功 選擇密鑰解密:1.正確密鑰 2.錯誤密鑰」。串口顯示「讀取的數據:爲:0x7E 0xDC 0xA3 0x7B 0xBA 0x53 0x84 0xAC 0x0B 0x75 0x50 0x45 0x2E 0xEC 0x4F 0x4F」。
按「2」鍵選擇錯誤的密鑰後,屏幕提示「A鍵確認解密」,此時串口顯示「將使用如下密鑰進行解密:0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00」。
按「A」 鍵確認解密後,屏幕提示「解密完成 A鍵返回」,此時串口顯示「解密後的數據爲:0xB9 0x8C 0xB6 0x40 0xA2 0xD2 0x83 0xD0 0x64 0x6E 0x54 0x26 0x86 0x6D 0x5A 0xF5」。而正確的原始數據爲:「0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F」,因此解密失敗。
實驗過程及結果:
一、打開「Z32開發指南\實驗8-SM2」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。
當左邊框出現「1設備已鏈接」,設備選擇中顯示芯片型號,此時就能夠下載程序了。
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗8的程序就下載進Z32的實驗板上了。
實驗9的內容是SM2加解密實驗。本實驗使用Z32內置函數庫實現加解密算法。
咱們用9針串口線將Z32模塊的串口與電腦USB接口鏈接。
首先在電腦上打開串口助手,選擇對應的串口號,設置波特率爲115200,偶校驗(Even),而後打開串口。
關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:12864屏幕上顯示「SM2實驗!請看串口助手」。
在字符串輸入框輸入數據「abc」,點擊發送。
輸入字符串「abc」發送,字符串顯示在串口調試助手上,如圖。
按下矩陣鍵盤「A」鍵,串口調試助手顯示數據「輸入的數據爲:abc」,並提示「按A鍵進行加密」。
按矩陣鍵盤上「A」鍵,加密後的數據顯示在串口調試助手上,如圖。
再按「A」鍵,進行解密,解密後的數據顯示在串口調試助手上。
實驗過程及結果:
一、打開「Z32開發指南\實驗10-SM3」目錄的工程文件。編譯工程,產生後綴名爲.bin的可執行代碼。
二、下載程序
將實驗箱接入電源,用USB公對公線將實驗箱的USB接口鏈接到電腦的USB接口上,在電腦上找到「Z32開發指南\2.軟件資料\Z32下載調試工具」目錄打開Z32下載調試工具NZDownloadTool.exe。打開Z32的電源開關前,按住Reboot按鍵不放,兩次打開電源開關,Z32便可被電腦識別,進行下載調試。
當左邊框出現「1設備已鏈接」,設備選擇中顯示芯片型號,此時就能夠下載程序了。
點擊「下載」,左邊狀態提示框更新顯示「程序下載成功!」實驗10的程序就下載進Z32的實驗板上了。
實驗9的內容是SM3數據加密實驗。本實驗使用Z32內置函數庫實現加密算法。
咱們用9針串口線將Z32模塊的串口與電腦USB接口鏈接。
首先在電腦上打開串口助手,選擇對應的串口號,設置波特率爲115200,偶校驗(Even),而後打開串口。
關閉Z32電源開關,再打開,程序自動運行,此時能夠看到實驗現象:液晶屏上顯示「SM2實驗!請看串口助手」。
串口助手上提示:「請輸入須要雜湊的數據(64字節之內),並按A鍵確認」。
在字符串輸入框輸入數據「wsq」,點擊發送。
按下「A」鍵後進行,加密,串口調試助手顯示被雜湊加密後的數據。
實驗過程及結果:
當Z32和ARM同時開啓時,會致使Z32中下載好的程序沒法成功運行,會影響到Z32接收到的數據從而使加解密的數據成爲亂碼。
#include <termios.h> #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <pthread.h> #define BAUDRATE B115200 #define COM1 "/dev/ttyO1" #define COM2 "/dev/ttyO1" #define ENDMINITERM 27 /* ESC to quit miniterm */ #define FALSE 0 #define TRUE 1 volatile int STOP=FALSE; volatile int fd; void child_handler(int s) { printf("stop!!!\n"); STOP=TRUE; } /*-------------------------------------------------------- */ void* keyboard(void * data) { int c; for (;;){ c=getchar(); if( c== ENDMINITERM){ STOP=TRUE; break ; } } return NULL; } /*-------------------------------------------------------- */ /* modem input handler */ void* receive(void * data) { int c; printf("read modem\n"); while (STOP==FALSE) { read(fd,&c,1); /* com port */ write(1,&c,1); /* stdout */ } printf("exit from reading modem\n"); return NULL; } /*-------------------------------------------------------- */ void* send(void * data) { int c='0'; printf("send data\n"); while (STOP==FALSE) /* modem input handler */ { c++; c %= 255; write(fd,&c,1); /* stdout */ usleep(100000); } return NULL; } /*--------------------------------------------------------*/ int main(int argc,char** argv) { struct termios oldtio,newtio,oldstdtio,newstdtio; struct sigaction sa; int ok; pthread_t th_a, th_b, th_c; void * retval; if( argc > 1) fd = open(COM2, O_RDWR ); else fd = open(COM1, O_RDWR ); //| O_NOCTTY |O_NONBLOCK); if (fd <0) { error(COM1); exit(-1); } tcgetattr(0,&oldstdtio); tcgetattr(fd,&oldtio); /* save current modem settings */ tcgetattr(fd,&newstdtio); /* get working stdtio */ newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD; /*ctrol flag*/ newtio.c_iflag = IGNPAR; /*input flag*/ newtio.c_oflag = 0; /*output flag*/ newtio.c_lflag = 0; newtio.c_cc[VMIN]=1; newtio.c_cc[VTIME]=0; /* now clean the modem line and activate the settings for modem */ tcflush(fd, TCIFLUSH); tcsetattr(fd,TCSANOW,&newtio); /*set attrib*/ sa.sa_handler = child_handler; sa.sa_flags = 0; sigaction(SIGCHLD,&sa,NULL); /* handle dying child */ pthread_create(&th_a, NULL, keyboard, 0); pthread_create(&th_b, NULL, receive, 0); pthread_create(&th_c, NULL, send, 0); pthread_join(th_a, &retval); pthread_join(th_b, &retval); pthread_join(th_c, &retval); tcsetattr(fd,TCSANOW,&oldtio); /* restore old modem setings */ tcsetattr(0,TCSANOW,&oldstdtio); /* restore old tty setings */ close(fd); exit(0); }