添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

(一)通信设计

1.包格式

2.包格式解释

通信标识,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

中止协议,并发送验证证书失败信息+\(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进展

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

    2.已解决的问题

    SM2公私钥生成
    自己签名课程做过的sm2
    sm234编译
    Compute SM2 signature and verify it by invoking EVP interface in OpenSSL 1.1.1
    使用openssl的EVP接口使用sm2算法加解密等操作
    openssl 1.1.1b 如何制作SM2公钥(在Ubuntu 19.04下测试通过)

    DER和PEM格式区别与解析,ASN1解析
    iOS X509证书的解析
    https://blog.csdn.net/kesay/article/details/46874699
    通过OpenSSL解析X509证书基本项
    ASN.1简介及OpenSSL中ASN.1接口使用举例
    通过OpenSSL解析X509证书基本项
    OpenSSL之X509系列之1---引言和X509概述
    X.509证书的解析、验证及使用
    x.509数字证书编码详解

    左边为test1()打印证书,右边为ASN1格式解析,ieout.cer是从IE浏览器导出的证书
  • 使用OpenSSL命令行生成证书请求和证书并与自己生成的进行比较
    基于国密算法的小型CA系统设计与实现.pdf
    国密SM2的证书制作及验证
  • 左边为test1()打印ca.cer证书(参照:国密SM2的证书制作及验证,使用命令行方式生成的根证书),
    右边为使用接口自己生成根证书
  • API函数使用参考
    openssl官网说明
  • 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 test4();
    函数功能:测试Cert_Gen()、Cert_Request_Gen_ex()、SavetoPem_ECPrikey()和SavetoDer();生成根证书和一个用户证书
    

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

    二、遇到的问题及解决

    1.指针问题:

  • EVP_PKEY绑定EC_KEY后,两者共享内存,释放时只需要释放一个
  • 使用i2d_X509(Cert, &pTmp1)时,pTmp1虽然是malloc()申请的内存,但是调用i2d_X509()后,pTmp1指向Cert的部分,就不符合动态分配的指针,后面不需要释放
  • 解决 C 语言中的 Free Invalid Pointer 错误
    munmap_chunk(): invalid pointer

    2.有些OpenSSL结构体的使用

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

    三、下周计划

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

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