《基于Arm实验箱的国密算法应用》课程设计 结题报告
- 小组成员姓名:20155206赵飞 20155220吴思其 20155234昝昕明
- 指导教师:娄嘉鹏
设计方案
题目要求:基于Arm实验箱的国密算法应用
三种平台:
Z32
ARM32+Linux
STM32
内容:
SM1, SM2,SM3算法测试
算法应用:混合密码系统
设计方案及可行性分析
运行老师给的范例代码,熟悉开发软件和开发板的使用;收集资料简单了解Z32,ARM的基本概念,然后实现ARM与Ubuntu映射文件。成功编译并运行代码。
详细设计思路
首先设计一个客户端与服务器能够互相接收,发送信息;再设计一个串口程序,可以通过超级终端打开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标识,这在通用上就大打折扣了,这一点需要考虑的
SM1, SM2,SM3算法测试:
1.LED闪烁实验
实验过程及结果:
1、打开“Z32开发指南\实验1-LED闪烁”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用USB公对公线将实验箱的USB接口连接到电脑的USB接口上,在电脑上找到“Z32开发指南\2.软件资料\Z32下载调试工具”目录打开Z32下载调试工具NZDownloadTool.exe。打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。
当左边框出现“1设备已连接”,设备选择中显示芯片型号,此时就可以下载程序了。
点击“下载”,左边状态提示框更新显示“程序下载成功!”实验1的程序就下载进Z32的实验板上了。
实验现象:
实验1的内容是对LED灯的操作,我们关闭Z32电源开关,再打开,程序自动运行,此时可以看到实验现象:Z32核心板上L2灯开始闪烁。
2.UART发送与中断接收实验
实验过程及结果:
1、打开“Z32开发指南\实验2-UART发送与中断接收”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用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”,并显示在串口助手上。
3.12864液晶屏串行显示实验
实验过程及结果:
1、打开“Z32开发指南\实验3-12864液晶屏串行显示”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用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,四行字符全部显示完成后清屏幕,重新循环显示。
4.GPIO0按键中断实验
实验过程及结果:
1、打开“Z32开发指南\实验4-GPIO0按键中断”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用USB公对公线将实验箱的USB接口连接到电脑的USB接口上,在电脑上找到“Z32开发指南\2.软件资料\Z32下载调试工具”目录打开Z32下载调试工具NZDownloadTool.exe。打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。
当左边框出现“1设备已连接”,设备选择中显示芯片型号,此时就可以下载程序了。
点击“下载”,左边状态提示框更新显示“程序下载成功!”实验4的程序就下载进Z32的实验板上了。
实验4的内容是按键中断,12864显示屏显示字符。
关闭Z32电源开关,再打开,程序自动运行,此时可以看到实验现象:12864屏幕第一行显示:“请按reboot按键:”
依次按下按键10次后,屏幕第二行显示0~9的数字。
5.矩阵键盘实验
实验过程及结果:
1、打开“Z32开发指南\实验5-矩阵键盘”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用USB公对公线将实验箱的USB接口连接到电脑的USB接口上,在电脑上找到“Z32开发指南\2.软件资料\Z32下载调试工具”目录打开Z32下载调试工具NZDownloadTool.exe。打开Z32的电源开关前,按住Reboot按键不放,两次打开电源开关,Z32即可被电脑识别,进行下载调试。
当左边框出现“1设备已连接”,设备选择中显示芯片型号,此时就可以下载程序了。
点击“下载”,左边状态提示框更新显示“程序下载成功!”实验5的程序就下载进Z32的实验板上了。
实验5的内容是读矩阵键盘键值并显示。
关闭Z32电源开关,再打开,程序自动运行,此时可以看到实验现象:12864屏幕第一行显示字符串
按下矩阵键盘上“A”键,屏幕第二行显示“A”。
按下“A”键显示图
6.TIMER定时器实验
实验过程及结果:
1、打开“Z32开发指南\实验6-TIMER定时器”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
Z32工程编译图
2、下载程序
将实验箱接入电源,用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灭。
7.SLE4428逻辑加密卡实验
实验过程及结果:
1、打开“Z32开发指南\实验7-SLE4428逻辑加密卡”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用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卡。
8.SM1加密实验
实验过程及结果:
1、打开“Z32开发指南\实验8-SM1”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
Z32工程编译图
2、下载程序
将实验箱接入电源,用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”键,则屏幕第一行显示“加密解密实验”,第二、三行分别显示选项“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”,所以解密失败。
9.SM2加密实验
实验过程及结果:
1、打开“Z32开发指南\实验8-SM2”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用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”键,进行解密,解密后的数据显示在串口调试助手上。
10.SM3加密实验
实验过程及结果:
1、打开“Z32开发指南\实验10-SM3”目录的工程文件。编译工程,产生后缀名为.bin的可执行代码。
2、下载程序
将实验箱接入电源,用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”键后进行,加密,串口调试助手显示被杂凑加密后的数据。
11.Z32与ARM间通信实验
实验过程及结果:
12.通过超级终端实现串口助手
课设中未能解决的问题
当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);
}