代码改变世界

加密API实现与测试

2022-05-29 16:42  陈冠昊  阅读(114)  评论(0编辑  收藏  举报

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,"cgh");
    strcpy(di.DeviceName,"cghSDF");
    strcpy(di.DeviceSerial,"20191319");
    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;
}

image
非对称算法(至少支持SM2)
按借助openssl实现了SM2算法的加密解密、签名验签
image
签名验签
image
对称算法(至少支持SM4)
image
杂凑算法
image