实验一-密码引擎-加密API实现与测试
1. 下载并查找GMT 0018-2012密码设备应用接口规范原始文档进行学习 (5分)
2 实现GMT 0018-2012密码设备应用接口规范的接口函数,至少实现:
-
1)设备管理中的打开设备,关闭设备,获取设备信息,产生随机数(4分)
-
2)密钥管理:
导出 ECC签名公钥 :SDF_ExportSignPublicKey_ECC ;
导出 ECC加密公钥:SDF_ExportEncPublicKey_ECC ;
产生 ECC非对称密钥对并输出:SDF_GenerateKeyPair_ECC K. (6分)
- 3)非对称算法(至少支持SM2):
外部密钥 ECC验证:SDF_ExternalVerify_ECC ;
内部密钥 ECC签名:SDF_InternalSign_ECC ;
内部密钥 ECC验证:SDF_InternalVerify_ECC ;
外部密钥 ECC加密:SDF_ExternalEncrypt_ECC (8分)
- 4)对称算法(至少支持SM4):
对称加密:SDF_Encrypt
对称解密:SDF_Dccrypt
计算MAC:SDF_CalculateMAC(6分)
- 5)杂凑算法(至少支持SM3):·
杂凑运算初始化:SDF_HashInit;
多包杂凑运算:SDF_HashUpdate·;
杂凑运算结束:SDF_HashFinal(6分)
3. 密钥管理要求(10分)
基于本标准设计、开发的密码设备在密钥管理方面,应满足以下要求:
-
1)设备密钥的使用不对应用系统开放;
-
2) 密钥必须用安全的方法产生并存储;
-
3) 在任何时间、任何情况下,除公钥外的密钥均不能以明文形式出现在密码设备外;
-
4) 密码设备内部存储的密钥应具备有效的密钥保护机制,防止解剖、探测和非法读取;
-
5) 密码设备内部存储的密钥应具备权限控制机制,防止非法使用和导出。
4. 设备状态要求(5分)
基于本标准设计、开发的密码设备在设备状态方面,应满足以下要求:
-
1) 密码设备应具有初始和就绪两个状态;
-
2) 未安装设备密钥的密码设备应处干初始状态,已安装设备密钥的密码设备应处于就绪状态;
-
3) 在初始状态下,除可读取设备信息、设备密钥的生成或恢复操作外,不能执行任何操作,生成或恢复设备密钥后,密码设备处于就绪状态;
-
4) 在就绪状态下,除设备密钥的生成或恢复操作外,应能执行任何操作;
-
5) 在就绪状态下进行的密钥操作,设备操作员应经过密码设备的认证。
代码
sdf.h
#ifndef _SDF_H
#define _SDF_H
typedef struct DeviceInfo_st{
unsigned char IssuerName[40];
unsigned char DeviceName[16];
unsigned char DeviceSerial[16];
unsigned int DeviceVersion;
unsigned int StandardVersion;
unsigned int AsymAlgAbility[2];
unsigned int SymAlgAbility;
unsigned int HashAlgAbility;
unsigned int BufferSize;
} DEVICEINFO;
#define SDR_OK 0x0
/*打开设备*/
int SDF_OpenDevice( void * * phDeviceHandle);
/*关闭设备*/
int SDF_CloseDevice( void * hDeviceHandle);
/*获取设备信息*/
int SDF_GetDeviceInfo(void * hSessionHandle,DEVICEINFO * pstDeviceInfo) ;
/*产生随机数*/
int SDF_GenerateRandom (void * hSessionHandle,unsigned int uiLength,unsigned char * pucRandom);
/*Error Code */
#define SDR_OK 0x0 //操作成功
#define SDR_BASE 0x01000000 //错误码基础值
# define SDR_UNKNOWERR SDR_BASE +Ox00000001 //未知错误
#define SDR_NOTSUPPORT SDR_BASE+0x00000002 //不支持的接口调用
#define SDR_COMMFAIL SDR_BASE+0x00000003 //与设备通信失败
#define SDR_HARDFAIL SDR_ BASE + 0x00000004 //运算模块无响应
#define SDR_OPENDEVICE SDR_ BASE +0x00000005 //打开设备失败
#define SDR_OPENSESSION SDR_BASE+ 0x00000006 //创建会话失败
#endif
main.c
#include<stdio.h>
#include<stdlib.h>
#include "sdf.h"
int main(){
void **pdh;
pdh = (void **)malloc(20);
int ret;
ret = SDF_OpenDevice(pdh);
if(ret != SDR_OK)
{
printf("打开设备失败! \n");
}
else
{
printf("成功打开设备!\n");
}
printf("查看设备信息\n");
DEVICEINFO a;
ret = SDF_GetDeviceInfo(*pdh,&a);
if(ret !=SDR_OK)
printf("查看设备信息失败!\n");
else
printf("查看设备信息成功!\n");
printf("设备名称:%s\n",a.DeviceName);
printf("设备版本号为%d\n",a.DeviceVersion);
printf("请输入随机数长度:\n");
int n;
scanf("%d",&n);
char string[100];
ret = SDF_GenerateRandom(*pdh,n,string);
if(ret !=SDR_OK)
printf("生成随机数失败!");
else
printf("生成的随机数为%s\n",string);
ret = SDF_CloseDevice(*pdh);
if(ret != SDR_OK)
{
printf("关闭设备失败!\n");
}
else
{
printf("成功关闭设备!\n");
}
}
sdf.c
#include<stdio.h>
#include <stdlib.h>
#include<string.h>
#include "sdf.h"
#include<time.h>
int SDF_OpenDevice( void * * phDeviceHandle)
{
return SDR_OK;
}
int SDF_CloseDevice( void * hDeviceHandle)
{
return SDR_OK;
}
int SDF_GetDeviceInfo(void * hSessionHandle,DEVICEINFO * pstDeviceInfo)
{
DEVICEINFO di;
strcpy(di.IssuerName,"lu");
strcpy(di.DeviceName,"LuSDF");
strcpy(di.DeviceSerial,"20191301");
di.DeviceVersion=1;
(*pstDeviceInfo)= di;
return SDR_OK;
}
int SDF_GenerateRandom (void * hSessionHandle,unsigned int uiLength,unsigned char * pucRandom)
{
int i=0;
char number[100];
srand(time(NULL));
number[i]=rand()%9+1+'0';
for(i=1;i<uiLength;i++)
{
number[i]=rand()%10+'0';
}
number[uiLength]='\0';
for(i=0;i<=uiLength;i++)
{
*(pucRandom+i)=number[i];
}
//itoa(num, pucRandom, 10);
printf("pucRandom的值为%s",pucRandom);
return SDR_OK;
}
非对称算法(至少支持SM2)
按照api要求,借助openssl实现了SM2算法的加密解密、签名验签。