2022_1_28_周汇报

一、进度

(一)通信设计

1.包格式

2.包格式解释

  • uid
    通信标识,32位

  • sender sequence
    数据包发送序号,32位

  • responder sequence
    数据包应答序号,32位

  • stage
    步骤标识序号,4位,加密秘钥协商4步、通信、结束2步

  • accept flag

    对面发送的包应答是有效的,1位,(累计确认,或者单个确认)

  • retranslate flag

    是否重传,1位

  • reset flag

    重置标志位,1位,表示有一方掉线或中断,重新开启后发现对方没按流程来时,通知对方清除数据从头开始

  • shared flag
    是否分段标识,1位

  • next flag
    当前分段是否继续标识,1位

  • 空着一位作保留或者后面添加

  • packet count
    累计包数,6位,单位为:一个包数据长度,现为1440字节

  • checked num
    校验和,16位

  • window size
    窗口大小,8位

  • timestamp
    时间戳,24位

  • reserved
    拓展+保留位,12字节

  • 共32字节

3.通信流程

所有部分除第一个包和通信阶段,从第二个包开始,要验证响应信息是否有效,有效设置accept-flag,无效accept-flag设置为0且reset-flag设置为1,重新开始
通信阶段accept-flag恒为1,reset-flag恒为0
1.协商部分

按照协商步骤计算后发送,设置stage为0x1、0x2、0x3、0x4

2.通信部分

所有通信包设置stage为0x5

加密通信部分($A$发起通信)

步骤1
$A$将信息用加密秘钥加密
$A$计算$E_k^{sm3}(message)$,将$E_k^{sm3}(message)$打包 B接受包
步骤2
$B$解密获取信息
$A$(无) $B$解密获取信息
3.结束

一方提出结束请求,另一方发送结束请求确认(必须要签名数据,签名包含头部),提出请求方还需要确认签名
设置stage为0x6、0x7、0x8

4.意外处理

  • 验证证书失败
    中止协议,并发送验证证书失败信息+\(sm3 Hash\),设置stage为0xA,设置reset-flag为1
  • 验证签名失败
    中止协议,并发送验证签名失败信息+\(sm3 Hash\),设置stage为0xB,设置reset-flag为1
  • 超时
    重传,stage不变,设置retranslate-flag为1
  • 收到重发的包
    舍弃
  • 加解密失败
    发送加解密失败信息+签名,设置stage为0xC,设置reset-flag为1(reset-flag为1,结合stage进行处理)
  • 机器断电或重启或断网
  • 内存占用过多,进程崩溃
  • 进程被结束掉
  • 建立连接时,服务器应用被阻塞
  • 端口不存在或未开放

(二)协议demo进展

1.思路

使用接口先生成SM2公私钥,再生成证书,最后模拟协商4步

2.已解决的问题

左边为test1()打印证书,右边为ASN1格式解析,ieout.cer是从IE浏览器导出的证书

左边为test1()打印ca.cer证书(参照:国密SM2的证书制作及验证,使用命令行方式生成的根证书),
右边为使用接口自己生成根证书

3.使用OpenSSL接口编程如下函数:

  • X509* ReadDer(char *filePath);
    /*DER编码的单个文件为*.cer*/
    /*
    函数功能:读取DER格式的X509证书
    */
    

    参考:DER证书读取保存和转换

  • int SavetoDer(X509 *Cert, char *filePath);
    /*
    函数功能:将X509结构体保存为DER格式文件
    */
    
  • int SavetoDer_X509Req(X509_REQ *req, char* filePath);
    /*
    函数功能:将X509_REQ结构体保存为DER格式文件
    */
    
  • int SavetoPem_ECPrikey(EC_KEY *eckey, char* filePath);
    /*
    函数功能:提取EC_KEY结构体中私钥并保存为PEM格式文件
    */
    
  • int SM2_KeyGen(EVP_PKEY **evpkeyout, EC_KEY **eckeyout);
    /*
    函数功能:生成SM2公私钥并保存到EC_KEY和EVP_PKEY结构体中
    */
    
  • int SM2_KeyGen_ex(EVP_PKEY * out);
    /*
    函数描述:SM2_KeyGen()的原始版本,未分割的函数
    */
    
  • void get_rand();
    /*
    函数功能:测试BN_rand()函数,指定位数随机数
    */
    

    参考:C语言利用OPENSSL 生成定制位的随机数

  • int Cert_Request_Gen(EVP_PKEY * evpPkey);
    /*
    函数描述:Cert_Request_Gen_ex()的原始版本
    */
    
  • X509_REQ* Cert_Request_Gen_ex(EVP_PKEY * evpPkey);
    /*
    函数功能:根据绑定EC_KEY的EVP_PKEY生成X509请求
    */
    

    参考:Openssl手册 25.4.1生成证书请求文件
    C++ (Cpp) X509_REQ_new Examples

  • int Cert_Gen(X509_REQ *req, X509* ca, X509** cert, char* ca_prikey_file, long sequence);
    /*
    函数功能:根据X509请求生成X509证书
    参数:
        req: X509请求
        ca : 签名的根证书
        cert: 生成的X509证书
        ca_prikey_file: 根证书私钥的PEM格式文件路径
        sequence :设置证书的序列号
    返回值:
        1, 证书生成成功
        0, 证书生成失败
    */
    

    参考:ASN1_TIME_to_generalizedtime
    X509_NAME_add_entry

  • void print_x509(X509* x);
    /*
    函数功能:打印X509结构体
    */
    
  • void print_pem_key(EC_KEY *ecKey);
    /*
    函数功能:打印PEM格式的EC_KEY
    */
    
  • void print_key_hex(EC_KEY *ecKey);
    /*
    函数功能:根据EC_KEY打印公私钥16进制
    */
    

    参考:公私钥转换成十六进制形式

  • void test2_d();
    /* test*() 说明:加上_d为未完成的函数*/
    - void test1();
    /*
    函数功能:测试ReadDer()和print_x509();输入DER格式文件路径,打印证书
    */
    
  • void test2();
    /*
    函数功能:测试SM2_KeyGen()、print_pem_key()和print_key_hex()
    */
    
  • void test3();
    /*
    函数功能:测试Cert_Request_Gen()
    */
    
  • void test4();
    /*
    函数功能:测试Cert_Gen()、Cert_Request_Gen_ex()、SavetoPem_ECPrikey()和SavetoDer();生成根证书和一个用户证书
    */
    

(后面找到的,同样是编程实现,做个对照)gmssl编程之签发X509证书

二、遇到的问题及解决

1.指针问题:

2.有些OpenSSL结构体的使用

在OpenSSL官网参考文档里,有时候可以直接搜索结构体开头的函数,或者在源码里/.../apps/和/.../crypto/里搜

三、下周计划

1.继续做协议的demo(经过证书生成,对OpenSSL的一些接口较为熟悉了)

2.改善通信部分,并尝试做通信部分的demo

posted @ 2022-01-24 13:05  20181324  阅读(128)  评论(0编辑  收藏  举报