智能密码钥匙(SKF)和密码机(SDF)标准接口实现会话密钥协商

        《GM/T 0018-2012 密码设备应用接口规范》定义了一系列使用密码机的接口函数和结构体,其接口函数以SDF_开头;《GM/T 0016-2012 智能密码钥匙密码应用接口规范》定义了一系列使用智能密码钥匙的接口函数和结构体,其接口函数以SKF_开头。

        SDF和SKF函数通过标准函数实现SM2密钥协商(即SM2密钥协商协议:通过交换中间参数各自生成会话密钥,会话密钥不出卡不出加密机,一次一密)实现客户端与服务端的加密通信。

 完整测试源码无法已上传,但审核未通过...【免费】智能密码钥匙(SKF)和密码机(SDF)标准接口实现会话密钥协商资源-CSDN文库

        使用智能密码钥匙(USBKEY)实现客户端流程:

        1、建立TCP连接;

        2、枚举设备(可选);

        3、连接设备;

        4、打开应用(如果不存在需要首先创建应用);

        5、打开容器(如果不存在需要首先创建容器);

        6、密钥协商(在此以发起方为例,智能密码钥匙也可以做响应方):

                1)导出加密公钥(不可以是签名公钥);

                2)计算密钥协商参数并导出临时公钥;

                3)发送发起方公钥和临时公钥(上面的公钥和临时公钥);

                4)接收响应方公钥和临时公钥;

                5)计算会话密钥。

        核心代码:

int _exchange_key(int sock)
{
    ULONG ret = SAR_FAIL;
    int valread = 0;
    
    char *pID = "1234567812345678";
    unsigned int pIDLen = 16;
    
    ECCPUBLICKEYBLOB pPubKey;
    ECCPUBLICKEYBLOB pPubTmpKey;
    ECCPUBLICKEYBLOB rPubKey;
    ECCPUBLICKEYBLOB rPubTmpKey;
    
    HANDLE phAgreementHandle;
    ULONG pulBlobLen = sizeof(pPubKey);
    ret = SKF_ExportPublicKey(pCon,
                                FALSE,
                                (BYTE *)&pPubKey,
                                &pulBlobLen);
    checkERROR("SKF_ExportPublicKey", ret);  
    
    ret = SKF_GenerateAgreementDataWithECC(pCon,
                                            SGD_SM4_ECB,
                                            &pPubTmpKey,
                                            (BYTE *)pID,
                                            pIDLen,
                                            &phAgreementHandle);
    checkERROR("SKF_GenerateAgreementDataWithECC", ret);
    
    printf("\npPubKey\n");
    for(int i = 0; i < (int)sizeof(pPubKey);i++)
        printf("%02x ", ((unsigned char *)&pPubKey)[i]);
    printf("\n\n");
    
    send(sock , &pPubKey , sizeof(pPubKey), 0 );
    printf("发送发起方公钥到服务端\n");
    send(sock , &pPubTmpKey , sizeof(pPubTmpKey), 0 );
    printf("发送发起方临时公钥到服务端\n");    

    valread = read(sock , &rPubKey, sizeof(rPubKey));
    printf("接收响应方公钥 valread=%d\n", valread );
    valread = read(sock , &rPubTmpKey, sizeof(rPubTmpKey));
    printf("接收响应方临时公钥 valread=%d\n", valread );  

    ret = SKF_GenerateKeyWithECC(phAgreementHandle,
                                    &rPubKey,
                                    &rPubTmpKey,
                                    (BYTE *)pID,
                                    pIDLen,
                                    &pKey);
    checkERROR("SKF_GenerateKeyWithECC", ret);
    
    return 0;
}

        注:一个智能密码钥匙(USBKEY)可以创建多个应用,每个应用可以创建多个容器,每个容器里有两对公私钥对,分别是签名密钥对和加密密钥对。

        使用密码机实现服务端流程:

        1、等待TCP连接;

        2、打开设备;

        3、打开会话;

        4、密钥协商:

                1)接收发起方公钥和临时公钥;

                2)计算会话密钥并导出公钥和临时公钥;

                3)发送公钥和临时公钥到客户端;

        核心代码:

int _exchange_key(int sock)
{
    ECCrefPublicKey pPubKey;
    ECCrefPublicKey pPubTmpKey;
    ECCrefPublicKey rPubKey;
    ECCrefPublicKey rPubTmpKey;
    
    int valread = 0;
    int rn = 0;
    
    unsigned char *pID = (unsigned char *)"1234567812345678";
    unsigned int pIDLen = 16;

    valread = read(sock , &pPubKey, sizeof(pPubKey));
    printf("接收发起方公钥 valread=%d\n", valread );
    valread = read(sock , &pPubTmpKey, sizeof(pPubTmpKey));
    printf("接收发起方临时公钥 valread=%d\n", valread );
    
    printf("\npPubKey\n");
    for(int i = 0; i < (int)sizeof(pPubKey);i++)
        printf("%02x ", ((unsigned char *)&pPubKey)[i]);
    printf("\n\n");
    
    rn = SDF_GenerateAgreementDataAndKeyWithECC(hSessionHandle,
                                                1,
                                                128,
                                                pID,pIDLen,
                                                pID,pIDLen,
                                                &pPubKey,
                                                &pPubTmpKey,
                                                &rPubKey,
                                                &rPubTmpKey,
                                                &pKey);
    checkERROR("SDF_GenerateAgreementDataAndKeyWithECC", rn);
    
    send(sock , &rPubKey , sizeof(rPubKey), 0 );
    printf("发送发起方公钥到客户端\n");
    send(sock , &rPubTmpKey , sizeof(rPubTmpKey), 0 );
    printf("发送发起方临时公钥到客户端\n");  

    return 0;
}

注:智能密码钥匙和密码机都可以做发起方或响应方,只是函数调用接口和次序不同;

        发起方和响应方都需要有ID,一般为字符串"1234567812345678",可以任意设置。

 完整测试源码无法已上传,但审核未通过...

【免费】智能密码钥匙(SKF)和密码机(SDF)标准接口实现会话密钥协商资源-CSDN文库

       

  • 11
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值