• 实验一密码引擎加密API实现与测试


    实验一-密码引擎-加密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算法的加密解密、签名验签。

    加解密

    签名验签

    对称算法(至少支持SM4)

    杂凑算法

  • 相关阅读:
    php图片上传代码
    数据库笔记
    数学函数类方法的使用.java
    有n人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位。
    现有有N个学生的数据记录,每个记录包括学号、姓名、三科成绩。 编写一个函数input,用来输入一个学生的数据记录。 编写一个函数print,打印一个学生的数据记录。 在主函数调用这两个函数,读取N条记录输入,再按要求输出。 N<100
    求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字
    分数相加减的代码(c++)
    Caesar cipher
    db2、Oracle存储过程引号用法
    CSS基础总结
  • 原文地址:https://www.cnblogs.com/20191301lhq/p/16263019.html
Copyright © 2020-2023  润新知