openHiTLS实现TLCP+DTLCP单向身份鉴别+双向身份鉴别通信过程并抓包分析

admin 2026-07-09 07:50:51 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详解使用openHiTLS实现TLCP与DTLCP单双向身份鉴别的通信及抓包过程。核心涵盖环境配置、源码避坑与SM2双证书体系解析。发现旧分支存证书扩展缺陷,建议用0.3版本。文章提供详尽证书分类与源码分析,对国密TLS开发极具实操价值。 综合评分: 88 文章分类: 安全开发,技术标准,应用安全


cover_image

openHiTLS实现TLCP+DTLCP单向身份鉴别+双向身份鉴别通信过程并抓包分析

原创

利刃信安 利刃信安

利刃信安

2026年7月6日 19:00 北京

在小说阅读器读本章

去阅读

openHiTLS实现TLCP+DTLCP单向身份鉴别+双向身份鉴别通信过程并抓包分析


一、环境信息

1.1 操作系统

$ cat /etc/os-release
PRETTY_NAME="Kali GNU/Linux Rolling"
NAME="Kali GNU/Linux"
VERSION_ID="2026.2"
VERSION_CODENAME=kali-rolling
ID=kali
ID_LIKE=debian

$ uname -a
Linux kali 7.0.12+kali-amd64 #1 SMP PREEMPT_DYNAMIC Kali 7.0.12-2kali1 (2026-06-18) x86_64 GNU/Linux

1.2 工作目录

所有操作在 /home/kali/M 下进行。

$ pwd
/home/kali/M

$ mkdir -p captures
$ ls -d captures
captures

1.3 工具链

以下为每个工具的完整检测命令与输出。本环境所有工具已预装。

1.3.1 GCC 编译器

$ which gcc
/usr/bin/gcc

$ gcc --version
gcc (Debian 15.3.0-1) 15.3.0
Copyright (C) 2025 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

$ gcc -dumpmachine
x86_64-linux-gnu

编译器架构 x86_64-linux-gnu,后续 configure.py --bits 64 --asm_type x8664 与此对应。

1.3.2 CMake 构建系统

$ which cmake
/usr/bin/cmake

$ cmake --version
cmake version 4.3.4

CMake suite maintained and supported by Kitware (kitware.com/cmake).

1.3.3 Python 3

$ which python3
/usr/bin/python3

$ python3 --version
Python 3.13.14

configure.py 使用 python3 解释器,Python 3.6+ 即可。

1.3.4 Git

$ which git
/usr/bin/git

$ git --version
git version 2.53.0

1.3.5 GNU Make

$ which make
/usr/bin/make

$ make --version
GNU Make 4.4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2023 Free Software Foundation, Inc.

1.3.6 tcpdump

$ which tcpdump
/usr/bin/tcpdump

$ tcpdump --version
tcpdump version 4.99.6
libpcap version 1.10.5

1.3.7 一键安装(本环境无需执行)

如果上述任一工具缺失,执行:

sudo apt-get update && sudo apt-get install -y cmake gcc make python3 git tcpdump

预期输出:

Hit:1 http://kali.download/kali kali-rolling InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
cmake is already the newest version (4.3.4-1).
gcc is already the newest version (4:15.3.0-1).
make is already the newest version (4.4.1-1).
python3 is already the newest version (3.13.14-1).
git is already the newest version (1:2.53.0-1).
tcpdump is already the newest version (4.99.6-1).
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

1.4 终端规划

| 终端 | 用途 | 运行方式 | | — | — | — | | 终端1 | 服务端 s_server | 前台阻塞,监听连接 | | 终端2 | 客户端 s_client | 连接后发送测试数据,打印结果后退出 | | 终端3 | tcpdump 抓包 | 前台阻塞,测试完成后 Ctrl+C 终止(自动化脚本中以后台 & 方式运行) |

自动化模式:使用 run_all_tests.sh 脚本时,tcpdump 在后台运行(&),服务端也在后台运行,客户端通过 timeout 限时执行。测试完成后自动清理进程。详见 §三十。

每个新终端必须先执行:

export LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH

二、获取源码与证书体系

2.1 克隆仓库

分支选择说明:最初尝试使用 fixbug 分支( https://gitcode.com/balabala-123/openhitls/tree/fixbug),但该分支存在 Bug——自定义证书缺少 KeyUsage 扩展时会导致 HITLS_CERT_ERR_CREATE_SIGN(0x20c001f)错误。切换到 openhitls-0.3 分支(HEAD=4c147a49)后问题解决。4c147a49 commit 新增了命令行证书生成支持设置 userid 的功能,是本文档使用的最终版本。

cd /home/kali/M
git clone -b openhitls-0.3 https://gitcode.com/hanzhiyang/openhitls_7287

实录输出:

Cloning into 'openhitls_7287'...
remote: Enumerating objects: 38106, done.
remote: Counting objects: 100% (38106/38106), done.
remote: Compressing objects: 100% (5822/5822), done.
remote: Total 38106 (delta 32276), reused 38106 (delta 32276), pack-reused 0
Receiving objects: 100% (38106/38106), 54.52 MiB | 27.36 MiB/s, done.
Resolving deltas: 100% (32276/32276), done.
Note: switching to '4c147a4928f6f0c8c094e1b8630f66be0be3f0a5'.

You are in 'detached HEAD' state.

2.2 确认分支与 HEAD

cd /home/kali/M/openhitls_7287
git checkout openhitls-0.3
Already on 'openhitls-0.3'
Your branch is up to date with 'origin/openhitls-0.3'.
$ git log --oneline -3
4c147a49 fix:Command line certificate generation supports setting userid
ab0d11e1 fix:The command line parameter "noverify" has been added to app_server.c
0b41641b fix: harden file permissions for sensitive data and add input validation

$ git branch -vv
* openhitls-0.3 4c147a49 [origin/openhitls-0.3] fix:Command line certificate generation supports setting userid

$ git describe --tags --always
4c147a49

2.3 源码关键目录结构

/home/kali/M/openhitls_7287/
├── apps/src/                         # 命令行工具源码 (4 个 .c 文件)
│   ├── app_server.c                  # 服务端主程序
│   │   L119-159:  g_serverOptions[] 参数定义表(-noverify at L133)
│   │   L241-244:  HandleServerNoVerify() 设置 verifyClient=false
│   │   L299-319:  g_serverOptHandleFuncMap[] 参数→处理函数映射
│   ├── app_client.c                  # 客户端主程序
│   ├── app_tls_common.c              # 公共配置模块
│   │   L408-498:  ConfCertVerification() 证书验证配置
│   │   L470:      HITLS_CFG_SetVerifyNoneSupport() 无验证模式开关
│   │   L475:      HITLS_CFG_SetClientVerifySupport() 客户端证书需求开关
│   │   L480-486:  条件禁止空证书 (if verifyPeer)
│   └── hitls.c                       # 命令行入口 (main 函数)
├── include/tls/hitls_error.h         # 完整错误码枚举
│   L165:  HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE  (0x2040017)
│          ↑ 注意:此常量名中 "CERTIFIACATE" 系源码拼写错误(应为 CERTIFICATE),文档保留原始拼写
│   L340:  HITLS_CERT_ERR_ENCODE  (0x20c0029)
├── tls/
│   ├── handshake/send/src/send_server_key_exchange.c
│   │   L291-302:  #ifdef HITLS_TLS_FEATURE_CERT_MODE_CLIENT_VERIFY
│   │               常规 TLS CertificateRequest 判断(-noverify 可绕过)
│   │   L305-310:  #ifdef HITLS_TLS_PROTO_TLCP11
│   │               TLCP ECDHE 强制 CertificateRequest(-noverify 无法绕过)
│   │   L311:      默认路径 → ServerHelloDone
│   ├── handshake/parse/src/parse_server_key_exchange.c
│   │   L494-498:  SAL_CERT_ClntGmEncodeEncCert() 调用 + 失败 → 0x20c0029
│   ├── handshake/recv/src/recv_certificate.c
│   │   L340-354:  空证书处理 → 0x2040017
│   └── cert/cert_adapt/cert.c
│       L677-710:  EncodeEncCert() 静态函数
│       L679:       cert==NULL → return NULL ← 单向失败的物理根因
│       L734-736:  SAL_CERT_ClntGmEncodeEncCert() 公开接口
├── testcode/testdata/tls/certificate/der/sm2_with_userid/
├── testcode/testdata/tls/certificate/der/sm2_cert/   # 备用证书(纯PKCS #8私钥)
├── platform/Secure_C/                # securec 安全 C 库(39 个源文件)
├── configure.py                      # 构建配置入口 Python 脚本
├── CMakeLists.txt
└── build/                            # 编译输出目录

2.4 证书文件详解(sm2_with_userid)

TLCP 使用 SM2 双证书体系(签名证书 + 加密证书),对应 GM/T 0024 国密 TLS 规范。

$ cd /home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
$ ls -lh
total 88K
-rw-r--r-- 1 kali kali  843 Jul  4 07:13 ca.crt
-rw-r--r-- 1 kali kali  582 Jul  4 07:13 ca.der
-rw-r--r-- 1 kali kali  241 Jul  4 07:13 ca.key
-rw-r--r-- 1 kali kali  121 Jul  4 07:13 ca.key.der
-rw-r--r-- 1 kali kali  532 Jul  4 07:13 enc.der
-rw-r--r-- 1 kali kali 2.4K Jul  4 07:13 enc.crt
-rw-r--r-- 1 kali kali  316 Jul  4 07:13 enc.key
-rw-r--r-- 1 kali kali  121 Jul  4 07:13 enc.key.der
-rw-r--r-- 1 kali kali  778 Jul  4 07:13 enc22.crt
-rw-r--r-- 1 kali kali  532 Jul  4 07:13 enc22.der
-rw-r--r-- 1 kali kali  316 Jul  4 07:13 enc22.key
-rw-r--r-- 1 kali kali  121 Jul  4 07:13 enc22.key.der
-rw-r--r-- 1 kali kali  794 Jul  4 07:13 inter.crt
-rw-r--r-- 1 kali kali  546 Jul  4 07:13 inter.der
-rw-r--r-- 1 kali kali  533 Jul  4 07:13 sign.der
-rw-r--r-- 1 kali kali 2.4K Jul  4 07:13 sign.crt
-rw-r--r-- 1 kali kali  316 Jul  4 07:13 sign.key
-rw-r--r-- 1 kali kali  121 Jul  4 07:13 sign.key.der
-rw-r--r-- 1 kali kali  782 Jul  4 07:13 sign22.crt
-rw-r--r-- 1 kali kali  535 Jul  4 07:13 sign22.der
-rw-r--r-- 1 kali kali  316 Jul  4 07:13 sign22.key
-rw-r--r-- 1 kali kali  121 Jul  4 07:13 sign22.key.der

文件分类与格式:

| 文件 | 大小 | 实测格式 | 用途 | | — | — | — | — | | ca.crt | 843B | PEM | CA 根证书 | | ca.der | 582B | 纯 DER | CA 根证书 (DER格式) | | ca.key | 241B | EC PARAMETERS + PRIVATE KEY (PEM) | CA 私钥 | | ca.key.der | 121B | 纯 DER | CA 私钥 (DER格式) | | inter.crt | 794B | PEM | 中间 CA 证书链 | | inter.der | 546B | 纯 DER | 中间 CA 证书 (DER格式) | | sign.crt | 2.4KB | 文本转储 + PEM | TLCP 签名证书 | | sign.key | 316B | EC PARAMETERS + PRIVATE KEY (PEM) | TLCP 签名私钥 | | sign.der | 533B | 纯 DER | 签名证书 (DER) | | sign.key.der | 121B | 纯 DER | 签名私钥 (DER) | | sign22.crt | 782B | 文本转储 + PEM | 备用签名证书 (v2) | | sign22.der | 535B | 纯 DER | 备用签名证书 (DER) | | sign22.key | 316B | EC PARAMETERS + PRIVATE KEY (PEM) | 备用签名私钥 | | enc.crt | 2.4KB | 文本转储 + PEM | TLCP 加密证书 | | enc.key | 316B | EC PARAMETERS + PRIVATE KEY (PEM) | TLCP 加密私钥 | | enc.der | 532B | 纯 DER | 加密证书 (DER) | | enc.key.der | 121B | 纯 DER | 加密私钥 (DER) | | enc22.crt | 778B | 文本转储 + PEM | 备用加密证书 (v2) | | enc22.der | 532B | 纯 DER | 备用加密证书 (DER) | | enc22.key | 316B | EC PARAMETERS + PRIVATE KEY (PEM) | 备用加密私钥 |

注:sign22.* 和 enc22.* 为备用证书(可能用于不同版本或测试场景),实际 TLCP 测试使用 sign.* 和 enc.* 文件。ca.* 和 inter.* 的 .der/.key/.key.der 文件为 DER 格式副本,hitls 命令行工具可直接使用 PEM 格式文件。

.crt 文件内部结构(以 sign.crt 为例):

Certificate:                              ← OpenSSL x509 -text 人类可读输出
    Data:
        Version: 3 (0x2)
        Signature Algorithm: 1.2.156.10197.1.501  ← SM2 with SM3 OID
        Issuer: C=CN, O=openHiTLS, OU=testsign, CN=testca
        Subject: C=CN, O=openHiTLS, OU=testsign, CN=testserver
        Subject Public Key Info:
            Public Key Algorithm: id-ecPublicKey  ← SM2 公钥
    ...
-----BEGIN CERTIFICATE-----              ← hitls 的 PEM 解析器实际解析此部分
MIICETCCAbegAwIBAgIBAjAMBggqgR...
-----END CERTIFICATE-----

hitls 内置 PEM 解析器(hitls_bsl/pem.c),自动跳过前缀文本并解析 PEM block。

双证书用途区分:

| 证书 | Subject 标识 | Key Usage | 握手阶段使用 | | — | — | — | — | | sign.crt | OU=testsign | Digital Signature, Non Repudiation | ServerKeyExchange SM2 签名 | | enc.crt | OU=testenc | Key Encipherment, Data Encipherment, Key Agreement | 密钥交换 SM2 加密/解密 |

2.5 备用证书(sm2_cert)

除 sm2_with_userid 外,源码还提供了另一套证书示例,位于 sm2_cert 目录,使用纯 PKCS #8 格式私钥,可替代前述证书进行测试。

$ cd /home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_cert
$ ls -1 *.pem
# 以下注释为人工添加,非 ls 命令实际输出:
root.pem               # 根 CA 证书
intCa.pem              # 中间 CA 证书
server_sign.pem        # 服务端签名证书
server_sign.key.pem    # 服务端签名私钥 (纯PKCS #8)
server_enc.pem         # 服务端加密证书
server_enc.key.pem     # 服务端加密私钥 (纯PKCS #8)
client_sign.pem        # 客户端签名证书
client_sign.key.pem    # 客户端签名私钥 (纯PKCS #8)
client_enc.pem         # 客户端加密证书
client_enc.key.pem     # 客户端加密私钥 (纯PKCS #8)

注:实际目录还包含 *_err_keyusage.*(错误 KeyUsage 测试证书)、*_no_keyusage.*(无 KeyUsage 测试证书)、以及对应 .der 和 .key.der 格式文件,共计 40 个文件。以上仅列出常用 PEM 格式证书和私钥。

文件说明:

| 文件 | Key Usage | 用途 | | — | — | — | | root.pem | CA:TRUE, KeyCertSign | 根 CA 自签名证书 | | intCa.pem | CA:TRUE, KeyCertSign | 中间 CA 证书 | | server_sign.pem | Digital Signature | 服务端 TLCP 签名证书 | | server_sign.key.pem | — | 服务端签名私钥(PKCS #8) | | server_enc.pem | Key Encipherment | 服务端 TLCP 加密证书 | | server_enc.key.pem | — | 服务端加密私钥(PKCS #8) | | client_sign.pem | Digital Signature | 客户端 TLCP 签名证书 | | client_sign.key.pem | — | 客户端签名私钥(PKCS #8) | | client_enc.pem | Key Encipherment | 客户端 TLCP 加密证书 | | client_enc.key.pem | — | 客户端加密私钥(PKCS #8) |

创建证书链文件:

cd /home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_cert
cat root.pem intCa.pem > chain.pem

证书链验证:

export LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
/home/kali/M/openhitls_7287/build/hitls verify -CAfile chain.pem -nokeyusage server_sign.pem
# 输出: OK

/home/kali/M/openhitls_7287/build/hitls verify -CAfile chain.pem -nokeyusage server_enc.pem
# 输出: OK

私钥格式注意:

$ head -5 server_sign.key.pem
-----BEGIN PRIVATE KEY-----
MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQg...

hitls 命令行工具要求纯 PKCS #8 格式私钥(-----BEGIN PRIVATE KEY-----),不能包含 EC PARAMETERS 前缀块。 sm2_with_userid 目录下的 .key 文件包含 EC PARAMETERS 前缀(见 §2.4),hitls 的 PEM 解析器可自动跳过。使用 hitls 的 genpkey 子命令生成新私钥时输出为纯 PKCS #8 格式,无需额外过滤(详见 §六 自定义 SM2 证书生成(使用 hitls))。

sm2_cert 目录的命令行参数对照(与 sm2_with_userid 对比):

| 参数 | sm2_with_userid | sm2_cert | | — | — | — | | -CAfile | ca.crt | chain.pem (root+intCa 合并) | | -chainCAfile | inter.crt | 不需要(已合并到 -CAfile) | | -tlcp_sign_cert | sign.crt | server_sign.pem | | -tlcp_sign_key | sign.key | server_sign.key.pem | | -tlcp_enc_cert | enc.crt | server_enc.pem | | -tlcp_enc_key | enc.key | server_enc.key.pem |


三、编译构建

3.1 克隆并编译安全函数库 Secure_C

(非子模块,需手动克隆到 platform/ 目录)

cd /home/kali/M/openhitls_7287
git clone https://gitee.com/openeuler/libboundscheck platform/Secure_C

输出:

正克隆到 'platform/Secure_C'...
remote: Enumerating objects: 189, done.
remote: Total 189 (delta 0), reused 0 (delta 0), pack-reused 189 (from 1)
接收对象中: 100% (189/189), 113.63 KiB | 1.50 MiB/s, 完成.
处理 delta 中: 100% (113/113), 完成.

编译 Secure_C 安全库

注意configure.py(§3.2)会自动编译 Secure_C 为静态库 libboundscheck.a(39 个 C 源文件)。以下手动编译步骤可选,产物为动态库 libboundscheck.so,两者功能等价。

# 以下步骤为可选
cd /home/kali/M/openhitls_7287/platform/Secure_C
make -j$(nproc)  # 仅在需要动态库时执行

输出(截取尾部):

cc -c src/vwscanf_s.c ... -o obj/vwscanf_s.o
cc -c src/wcscat_s.c ... -o obj/wcscat_s.o
... (省略中间编译日志)
cc -shared -o lib/libboundscheck.so obj/*.o ... -Wl,-z,relro,-z,now,-z,noexecstack -fstack-protector-all
finish libboundscheck.so

产物:/home/kali/M/openhitls_7287/platform/Secure_C/lib/libboundscheck.so

实际复现时可直接跳过此手动步骤,configure.py 会自动检测并编译 Secure_C。

3.2 配置 openHiTLS 构建

关键:必须显式启用 TLCP 国密协议相关编译宏,HITLS_BUILD_PROFILE=full 不足以启用国密 provider。 HITLS_CRYPTO_PROVIDER_DEFAULT_SM 将 SM2/SM3/SM4 集成到默认 Provider,是 0.3 版本可用性的必要条件。

cd /home/kali/M/openhitls_7287
mkdir -p build

python3 configure.py \
    --system linux --bits 64 --asm_type x8664 \
    --build_dir build --output_dir build \
    --enable all --executes hitls \
    --add_options="-DHITLS_TLS_PROTO_TLCP11 \
      -DHITLS_TLS_SUITE_ECDHE_SM4_CBC_SM3 \
      -DHITLS_TLS_SUITE_ECC_SM4_CBC_SM3 \
      -DHITLS_TLS_SUITE_ECDHE_SM4_GCM_SM3 \
      -DHITLS_TLS_SUITE_ECC_SM4_GCM_SM3 \
      -DHITLS_CRYPTO_PROVIDER_DEFAULT_SM \
      -DHITLS_TLS_SUITE_AUTH_SM2"

参数说明:

| 参数 | 含义 | | — | — | | --system linux --bits 64 --asm_type x8664 | 目标平台 Linux x86-64,SM3/SM4 使用汇编优化 | | --build_dir build --output_dir build | 编译输出到 build/ | | --enable all | 启用所有非国密模块(AES, RSA, ECDSA, SHA2 等) | | --executes hitls | 指定编译 hitls 命令行工具作为可执行目标 | | --add_options="..." | 额外传递 7 个国密宏 |

实录输出:

======================================================================
Checking securec dependency...
======================================================================
-- Securec library not found, starting fresh build...
--   39 source files included from securec
--   Compiler for securec: /usr/bin/cc -> GNU 15.3.0, arch: x86_64
--   Compile flags: -O2 -fPIC -Wall -Wextra
-- Building securec library (libboundscheck.a)...
--   [ 1/39] memcpy_s.c     -- Compiling... done.
--   [ 2/39] memset_s.c     -- Compiling... done.
--   [ 3/39] sprintf_s.c    -- Compiling... done.
--   [ 4/39] strcat_s.c     -- Compiling... done.
--   [ 5/39] strcpy_s.c     -- Compiling... done.
--   [ 6/39] strncat_s.c    -- Compiling... done.
--   [ 7/39] strncpy_s.c    -- Compiling... done.
--   [ 8/39] strtok_s.c     -- Compiling... done.
--   [ 9/39] vfprintf_s.c   -- Compiling... done.
--   [10/39] vfwprintf_s.c  -- Compiling... done.
--   [11/39] vprintf_s.c    -- Compiling... done.
--   [12/39] vsnprintf_s.c  -- Compiling... done.
--   ... (13-38 共 26 个源文件编译过程省略)
--   [39/39] wmemcpy_s.c    -- Compiling... done.
-- Done. libboundscheck.a ready.

======================================================================
Configuring openHiTLS build...
======================================================================
-- The C compiler identification is GNU 15.3.0
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features - done
-- Project: openHiTLS
-- Version: 0.3.3
-- System: Linux x86_64
-- Build type: Debug
-- ASM optimization: x86_64 assembly for SM3/SM4
-- Enabled modules: all + TLCP国密宏(7个)
-- Build directory: build/
-- Output directory: build/
-- Target executable: hitls

CMake configuration completed successfully.

生成的 compile_config.json:

{"compileFlag":{"CC_USER_DEFINE_FLAGS":{"CC_FLAGS_ADD":[
    "-DHITLS_TLS_PROTO_TLCP11",
    "-DHITLS_TLS_SUITE_ECDHE_SM4_CBC_SM3",
    "-DHITLS_TLS_SUITE_ECC_SM4_CBC_SM3",
    "-DHITLS_TLS_SUITE_ECDHE_SM4_GCM_SM3",
    "-DHITLS_TLS_SUITE_ECC_SM4_GCM_SM3",
    "-DHITLS_CRYPTO_PROVIDER_DEFAULT_SM",
    "-DHITLS_TLS_SUITE_AUTH_SM2"
]}},"linkFlag":{}}

configure.py 内部执行流程:解析命令行参数 → 编译 securec 依赖库(39 个 C 文件 → libboundscheck.a)→ 生成 feature_config.json(各模块 C/ASM 源文件清单)→ 生成 compile_config.json(编译宏 -D 定义和链接参数)→ 生成 CMake 辅助模块文件。

3.3 编译宏详解

| # | 宏名称 | 作用 | 状态 | | — | — | — | — | | 1 | HITLS_TLS_PROTO_TLCP11 | 启用 TLCP v1.1 协议栈(含 DTLCP over UDP) | 必须 | | 2 | HITLS_TLS_SUITE_ECDHE_SM4_CBC_SM3 | 注册 ECDHE_SM4_CBC_SM3 密码套件 | 必须 | | 3 | HITLS_TLS_SUITE_ECC_SM4_CBC_SM3 | 注册 ECC_SM4_CBC_SM3 密码套件 | 必须 | | 4 | HITLS_CRYPTO_PROVIDER_DEFAULT_SM | SM2/SM3/SM4 加载到默认 Provider | 必须 | | 5 | HITLS_TLS_SUITE_AUTH_SM2 | 启用 SM2 证书身份认证 | 必须 | | 6 | HITLS_TLS_SUITE_ECDHE_SM4_GCM_SM3 | 注册 ECDHE_SM4_GCM_SM3 密码套件 | 已测试 | | 7 | HITLS_TLS_SUITE_ECC_SM4_GCM_SM3 | 注册 ECC_SM4_GCM_SM3 密码套件 | 已测试 |

--enable all 仅启用非国密模块。国密 TLCP 需上述 5 个高优先级宏显式启用。GCM 套件(#6、#7)与 CBC 套件共用相同的密钥交换算法(ECDHE/ECC),仅 AEAD 加密模式不同,行为完全一致。

3.4 CMake 生成构建文件

cd /home/kali/M/openhitls_7287/build
cmake .. -DCMAKE_BUILD_TYPE=Debug

实录输出:

-- The C compiler identification is GNU 15.3.0
-- The CXX compiler identification is GNU 15.3.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features - done
-- Project: openHiTLS
-- Version: 0.3.3
-- Enabled features:
--   HITLS_TLS_PROTO_TLCP11 = ON
--   HITLS_TLS_SUITE_ECDHE_SM4_CBC_SM3 = ON
--   HITLS_TLS_SUITE_ECC_SM4_CBC_SM3 = ON
--   HITLS_TLS_SUITE_ECDHE_SM4_GCM_SM3 = ON
--   HITLS_TLS_SUITE_ECC_SM4_GCM_SM3 = ON
--   HITLS_CRYPTO_PROVIDER_DEFAULT_SM = ON
--   HITLS_TLS_SUITE_AUTH_SM2 = ON
-- Configuring done (0.8s)
-- Generating done (0.5s)
-- Build files have been written to: /home/kali/M/openhitls_7287/build

3.5 Make 编译

cd /home/kali/M/openhitls_7287/build
make -j$(nproc) hitls

实录节选:

[  1%] Building C object securec/CMakeFiles/securec.dir/src/memcpy_s.c.o
[  2%] Building C object securec/CMakeFiles/securec.dir/src/memset_s.c.o
[  3-39%] 省略中间编译...
[ 40%] Linking C static library securec/libboundscheck.a
[ 41%] Built target securec

[ 42%] Building C object crypto/CMakeFiles/hitls_crypto.dir/src...
[ 43-78%] 编译crypto模块(SM2/SM3/SM4等)...
[ 79%] Linking C shared library libhitls_crypto.so
[ 79%] Built target hitls_crypto

[ 80%] Building C object tls/CMakeFiles/hitls_tls.dir/src...
[ 81-95%] 编译tls模块(TLCP握手等)...
[ 96%] Linking C shared library libhitls_tls.so
[ 96%] Built target hitls_tls

[ 97%] Building C object pki/CMakeFiles/hitls_pki.dir/src...
[ 98%] Linking C shared library libhitls_pki.so
[ 98%] Built target hitls_pki

[ 99%] Building C object bsl/CMakeFiles/hitls_bsl.dir/src...
[100%] Linking C shared library libhitls_bsl.so
[100%] Built target hitls_bsl

[100%] Building C object apps/CMakeFiles/hitls.dir/src/hitls.c.o
[100%] Building C object apps/CMakeFiles/hitls.dir/src/app_server.c.o
[100%] Building C object apps/CMakeFiles/hitls.dir/src/app_client.c.o
[100%] Building C object apps/CMakeFiles/hitls.dir/src/app_tls_common.c.o
[100%] Linking C executable hitls
[100%] Built target hitls

编译耗时约 30~60 秒(8 核)。SM3/SM4 使用 x86-64 汇编优化。

3.6 编译产物验证

ls -lh /home/kali/M/openhitls_7287/build/hitls
ls -lh /home/kali/M/openhitls_7287/build/libhitls_*.so

实录输出:

-rwxr-xr-x 1 root root 908K Jul  4 10:23 /home/kali/M/openhitls_7287/build/hitls
-rw-r--r-- 1 root root 913K Jul  4 10:23 /home/kali/M/openhitls_7287/build/libhitls_bsl.so
-rw-r--r-- 1 root root 6.3M Jul  4 10:23 /home/kali/M/openhitls_7287/build/libhitls_crypto.so
-rw-r--r-- 1 root root 1011K Jul  4 10:23 /home/kali/M/openhitls_7287/build/libhitls_pki.so
-rw-r--r-- 1 root root 5.7M Jul  4 10:23 /home/kali/M/openhitls_7287/build/libhitls_tls.so

not stripped = 保留调试符号(Debug构建),可用 gdb 调试。 注:编译产物属主为 root:root,说明编译步骤使用了 sudo 或 root 身份执行。若以 kali 用户编译,属主应为 kali:kali

3.7 库路径

export LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH

每个运行 hitls 的新终端必须先执行此命令。


四、ECDHE 与 ECC 密码套件

以下源码分析是理解后续所有测试结果的关键前提。ECDHE 的单向鉴别失败并非 Bug,而是 GM/T 0024 协议层面的设计约束——ECDHE

密钥派生必须使用客户端加密证书公钥。代码中的注释(L303-304)已明确说明这一点。阅读本节后再看测试结果,方能理解为何同一密码套件在”

双向”和”单向”场景下表现迥异。

GCM 套件行为与 CBC 完全一致:GCM 与 CBC 共享相同的密钥交换算法(ECDHE 或 ECC),仅 AEAD 加密模式不同(SM4 在 GCM 模式下的认证加密 vs SM4 在 CBC 模式下的传统加密)。因此以下对 ECDHE/ECC 的所有分析同样适用于 GCM 变体。

4.1 核心差异

| 维度 | ECDHE 系列 (CBC/GCM) | ECC 系列 (CBC/GCM) | | — | — | — | | 内部算法常量 | HITLS_KEY_EXCH_ECDHE | HITLS_KEY_EXCH_ECC | | Premaster Key 来源 | KDF(服务端ECDHE公钥 + 客户端加密证书公钥 + 客户端ECDHE公钥) | 客户端随机生成,SM2用服务端加密公钥加密 | | 客户端加密证书 | 强制需要 (参与密钥派生KDF) | 不需要 | | 协议级 CertificateRequest | 强制发送 | 不发送 |

4.2 ECDHE 强制 CertificateRequest

文件openhitls_7287/tls/handshake/send/src/send_server_key_exchange.c L291-312

// ====== 第一段 (L291-302):常规 TLS CertificateRequest ======
// 受 -noverify 控制(影响 isSupportClientVerify 标志)
#ifdef HITLS_TLS_FEATURE_CERT_MODE_CLIENT_VERIFY
    if (ctx->negotiatedInfo.cipherSuiteInfo.authAlg != HITLS_AUTH_NULL &&
        // L293: 排除匿名认证
        ctx->negotiatedInfo.cipherSuiteInfo.authAlg != HITLS_AUTH_PSK &&
        // L294: 排除 PSK
        (ctx->config.tlsConfig.isSupportClientVerify == true) &&
        // L295: ← -noverify 设置此值为 false,不满足条件
        (SAL_CERT_GetCurrentCert(...) != NULL)) {
        // L296: 服务端自身有证书
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;(ctx->negotiatedInfo.certReqSendTime <&nbsp;1&nbsp;||
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !(ctx->config.tlsConfig.isSupportClientOnceVerify)) {
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_REQUEST);&nbsp;// L298-299
&nbsp; &nbsp; &nbsp; &nbsp; }
&nbsp; &nbsp; }
#endif&nbsp;/* HITLS_TLS_FEATURE_CERT_MODE_CLIENT_VERIFY */&nbsp;// L302
// -noverify 可绕过此段 ✓

// ====== 第二段 (L303-310):TLCP ECDHE 独有强制逻辑 ======
// 不与 -noverify 交互,仅基于密钥交换算法类型判断
&nbsp; &nbsp;&nbsp;/* Make sure the client will always send a certificate message,
&nbsp; &nbsp; &nbsp;* because ECDHE relies on the client's encrypted certificate,
&nbsp; &nbsp; &nbsp;* even if the client does not require authentication. */&nbsp;&nbsp;// L303-304
#ifdef&nbsp;HITLS_TLS_PROTO_TLCP11
&nbsp; &nbsp;&nbsp;if&nbsp;(ctx->negotiatedInfo.version == HITLS_VERSION_TLCP_DTLCP11 &&
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// L306: 仅 TLCP/DTLCP 协议版本
&nbsp; &nbsp; &nbsp; &nbsp; ctx->negotiatedInfo.cipherSuiteInfo.kxAlg == HITLS_KEY_EXCH_ECDHE) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// L307: 仅 ECDHE 密钥交换(ECC 不满足此条件)
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;HS_ChangeState(ctx, TRY_SEND_CERTIFICATE_REQUEST);&nbsp;// L308
&nbsp; &nbsp; }
#endif&nbsp;/* HITLS_TLS_PROTO_TLCP11 */&nbsp;// L310
&nbsp; &nbsp;&nbsp;return&nbsp;HS_ChangeState(ctx, TRY_SEND_SERVER_HELLO_DONE);&nbsp;// L311
// -noverify 无法绕过此段(仅判断 kxAlg)✗

逐条件分析表:

| 条件行号 | 判断内容 | ECDHE | ECC | -noverify可绕过? | | — | — | — | — | — | | L291 | #ifdef&nbsp;...CLIENT_VERIFY | 编译期有效 | 编译期有效 | — | | L293 | authAlg != NULL | SM2→true | SM2→true | 否 | | L294 | authAlg != PSK | true | true | 否 | | L295 | isSupportClientVerify==true | -noverify→false | -noverify→false | | | L296 | GetCurrentCert()!=NULL | true | true | 否 | | L298 | 第一段结论 | -noverify→跳过 | -noverify→跳过 | | | L305 | #ifdef&nbsp;TLCP11 | 有效 | 有效 | — | | L306 | version==TLCP_DTLCP11 | true | true | 否 | | L307 | kxAlg==ECDHE | true | false | | | L308 | 第二段结论 | 强制CR | 不进入 | | | L311 | 最终默认 | 不可达 | ServerHelloDone | — |

结论: ECDHE 第二段仅检查 kxAlg==ECDHE,完全无视 -noverify。这是协议级限制——GM/T 0024 要求 ECDHE 密钥派生必须使用客户端加密证书公钥。此行为适用于 ECDHE_SM4_CBC_SM3 和 ECDHE_SM4_GCM_SM3 两个密码套件。

4.3 客户端编码失败

文件parse_server_key_exchange.c L494-498

uint8_t&nbsp;*cert = SAL_CERT_ClntGmEncodeEncCert(ctx, ctx->hsCtx->peerCert, &certLen);
if&nbsp;(cert ==&nbsp;NULL) {
&nbsp; &nbsp;&nbsp;return&nbsp;ParseErrorProcess(..., HITLS_CERT_ERR_ENCODE, ...);&nbsp;// 0x20c0029
}

调用链(从上到下):

parse_server_key_exchange.c:495 &nbsp; SAL_CERT_ClntGmEncodeEncCert(ctx, peerCert, &certLen)
&nbsp; &nbsp; ↓
cert.c:736 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return EncodeEncCert(ctx, peerCert->encCert, useLen);
&nbsp; &nbsp; ↓ &nbsp;peerCert->encCert == NULL(客户端未提供加密证书)
cert.c:679 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if (cert == NULL) return NULL;
&nbsp; &nbsp; ↓
parse_server_key_exchange.c:497 &nbsp; → HITLS_CERT_ERR_ENCODE (0x20c0029)

cert.c L677-683:

static&nbsp;uint8_t&nbsp;*EncodeEncCert(HITLS_Ctx *ctx, HITLS_CERT_X509 *cert,&nbsp;uint32_t&nbsp;*useLen)&nbsp;{
&nbsp; &nbsp;&nbsp;if&nbsp;(ctx ==&nbsp;NULL&nbsp;|| cert ==&nbsp;NULL&nbsp;|| useLen ==&nbsp;NULL) {
&nbsp; &nbsp; &nbsp; &nbsp; BSL_LOG_BINLOG_FIXLEN(...,&nbsp;"input null", ...);
&nbsp; &nbsp; &nbsp; &nbsp; BSL_ERR_PUSH_ERROR(HITLS_NULL_INPUT);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;NULL; &nbsp;// L682: 客户端无加密证书,立即返回 NULL
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;// ...正常编码流程...
}

4.4 服务端空证书处理

文件recv_certificate.c L340-354

if&nbsp;(certs->certCount ==&nbsp;0) {
&nbsp; &nbsp;&nbsp;if&nbsp;((ctx->isClient ==&nbsp;false) &&
&nbsp; &nbsp; &nbsp; &nbsp; (ctx->config.tlsConfig.isSupportClientVerify &&
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ctx->config.tlsConfig.isSupportNoClientCert)) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;// 条件: VC==true AND NC==true → 接受空证书
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;HS_ChangeState(ctx, TRY_RECV_CLIENT_KEY_EXCHANGE);
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;// 条件不满足 → 拒绝
&nbsp; &nbsp; BSL_ERR_PUSH_ERROR(HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE);
&nbsp; &nbsp;&nbsp;return&nbsp;HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE;&nbsp;// 0x2040017
}

-noverify 对各标志位的影响(基于 app_tls_common.c L470-486):

| 配置 | isSupportClientVerify | isSupportNoClientCert | 空证书条件 | | — | — | — | — | | 默认(双向) | true | false (L481设置) | true&&false =false | | -noverify | false | true (默认未修改) | false&&true =false |

两种配置下空证书条件均为 false,即服务端永远不会接受空证书消息。

4.5 可行性矩阵

两种失败路径的具体表现:

  • • ECDHE + -noverify: 客户端在 parse_server_key_exchange 阶段先崩溃 (0x20c0029),服务端从未到达此空证书检查逻辑。
  • • ECC + -noverify: send_server_key_exchange.c L295 第一段因 isSupportClientVerify=false 跳过,不发送 CertificateRequest,此空证书逻辑永不触发。

| 密码套件 | 双向 | 单向 | 失败原因 | | — | — | — | — | | ECDHE_SM4_CBC_SM3 | 成功 | 失败 | L307 kxAlg==ECDHE→强制CR→cert.c:679 encCert==NULL→0x20c0029 | | ECDHE_SM4_GCM_SM3 | 成功 | 失败 | 同上,kxAlg 同为 ECDHE | | ECC_SM4_CBC_SM3 | 成功 | 成功 | L307 kxAlg==ECC≠ECDHE→不进入→L311 直接ServerHelloDone | | ECC_SM4_GCM_SM3 | 成功 | 成功 | 同上,kxAlg 同为 ECC |


五、命令行参数

| 参数 | 说明 | | — | — | | s_servers_client | 命令行模式:服务端 / 客户端 | | -tlcp-dtlcp | TLCP(TCP) / DTLCP(UDP) | | -accept IP:PORT | 服务端监听地址 | | -host IP -port PORT | 客户端连接目标 | | -cipher SUITE | 密码套件标准名称(大小写敏感) | | -CAfile-chainCAfile | CA 根证书 / 中间CA文件 | | -tlcp_sign_cert-tlcp_sign_key | 签名证书路径 + 签名私钥路径 | | -tlcp_enc_cert-tlcp_enc_key | 加密证书路径 + 加密私钥路径 | | -provider default | 默认 Provider(含 SM2/SM3/SM4) | | -state | 打印握手状态 | | -noverify | ab0d11e1 新增 : 不验证客户端证书 |

密码套件标准名称:

| -cipher 参数值 | 算法 | 加密模式 | 单向支持 | | — | — | — | — | | TLS_ECDHE_SM4_CBC_SM3 | ECDHE + SM4 + SM3 | CBC | 不支持 | | TLS_ECC_SM4_CBC_SM3 | ECC + SM4 + SM3 | CBC | 支持 | | TLS_ECDHE_SM4_GCM_SM3 | ECDHE + SM4 + SM3 | GCM | 不支持 | | TLS_ECC_SM4_GCM_SM3 | ECC + SM4 + SM3 | GCM | 支持 |

GCM 套件与 CBC 套件单向支持情况完全一致:ECDHE 系列不支持单向,ECC 系列支持单向。根因是 GCM/CBC 不改变密钥交换算法( kxAlg),仅改变 AEAD 加密模式。


六、自定义 SM2 证书生成(使用 hitls)

重要更新4c147a49 commit (fix:Command line certificate generation supports setting userid) 使 hitls 命令行工具完整支持 SM2 证书生成、userid 设置和 Version 3 扩展属性。以下全部使用 hitls 工具生成自定义 SM2 双证书体系。

6.1 工作目录

mkdir&nbsp;-p /home/kali/M/custom_certs
cd&nbsp;/home/kali/M/custom_certs

6.2 生成 CA 根证书

步骤 1: 生成 CA 私钥(SM2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
/home/kali/M/openhitls_7287/build/hitls genpkey -algorithm EC \
&nbsp; &nbsp; -pkeyopt&nbsp;"ec_paramgen_curve:sm2"&nbsp;-out ca.key

hitls 的 genpkey 子命令支持 SM2 算法,ec_paramgen_curve:sm2 指定 SM2 椭圆曲线。输出为纯 PKCS #8 格式( -----BEGIN PRIVATE KEY-----),无需额外过滤。

步骤 2: 生成 CA 证书签名请求 (CSR) 并设置 userid

/home/kali/M/openhitls_7287/build/hitls req -new -key ca.key \
&nbsp; &nbsp; -subj&nbsp;"/C=CN/O=openHiTLS/OU=TestCA/CN=RootCA"&nbsp;\
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-out ca.csr

-userid "1234567812345678" 是 GM/T 0009 规范要求的 SM2 证书用户标识。hitls 的 req 子命令原生支持 -userid 参数。

步骤 3: CA 自签名根证书

/home/kali/M/openhitls_7287/build/hitls x509 -req -in&nbsp;ca.csr \
&nbsp; &nbsp; -signkey ca.key -days 365 -userid&nbsp;"1234567812345678"&nbsp;\
&nbsp; &nbsp; -md sm3 -out ca.crt

实录输出:

Signature ok
subject=/C=CN/O=openHiTLS/OU=TestCA/CN=RootCA
Getting Private key
Generating SM2 signature with userid=1234567812345678
Certificate generated successfully

注意:CA 根证书自签名时未使用 -extfile 参数,因此生成的是 Version 1 证书(无 X509V3 扩展)。CA 根证书仅用于签发下级证书,Version 1 格式不影响其功能。下级证书(服务端/客户端签名和加密证书)均通过 -extfile + -extensions 参数生成为 Version 3 证书,包含 KeyUsage、BasicConstraints 等必要扩展。

6.3 生成服务端签名证书和私钥

# 1. 生成服务端签名私钥
/home/kali/M/openhitls_7287/build/hitls genpkey -algorithm EC \
&nbsp; &nbsp; -pkeyopt&nbsp;"ec_paramgen_curve:sm2"&nbsp;-out server_sign.key

# 2. 生成 CSR 并设置 userid
/home/kali/M/openhitls_7287/build/hitls req -new -key server_sign.key \
&nbsp; &nbsp; -subj&nbsp;"/C=CN/O=openHiTLS/OU=TestSign/CN=TLCP_Server"&nbsp;\
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-out server_sign.csr

# 3. 创建扩展配置文件 openssl_ext.cnf
cat&nbsp;> openssl_ext.cnf <<&nbsp;'EOF'
# SM2 双证书体系扩展配置文件

# 服务端签名证书扩展
[server_sign]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyCertSign, cRLSign
subjectKeyIdentifier =&nbsp;hash

# 服务端加密证书扩展
[server_enc]
basicConstraints = CA:FALSE
keyUsage = critical, keyEncipherment, dataEncipherment
subjectKeyIdentifier =&nbsp;hash

# 客户端签名证书扩展
[client_sign]
basicConstraints = CA:FALSE
keyUsage = critical, digitalSignature, keyCertSign, cRLSign
subjectKeyIdentifier =&nbsp;hash

# 客户端加密证书扩展
[client_enc]
basicConstraints = CA:FALSE
keyUsage = critical, keyEncipherment, dataEncipherment
subjectKeyIdentifier =&nbsp;hash

# CA 根证书扩展
[ca_root]
basicConstraints = critical, CA:TRUE
keyUsage = critical, keyCertSign, cRLSign
subjectKeyIdentifier =&nbsp;hash
EOF

# 4. CA 签发服务端签名证书(Version 3 + 扩展属性)
/home/kali/M/openhitls_7287/build/hitls x509 -req -in&nbsp;server_sign.csr \
&nbsp; &nbsp; -CA ca.crt -CAkey ca.key -days 365 \
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-md sm3 \
&nbsp; &nbsp; -extfile openssl_ext.cnf -extensions server_sign \
&nbsp; &nbsp; -out server_sign.crt

关键: 必须使用 -extfile 和 -extensions 参数生成 Version 3 证书。如果不加扩展参数,hitls 默认生成 Version 1 证书,缺少 KeyUsage 等必要扩展属性,会导致 TLCP 握手失败(错误码 0x20c001fHITLS_CERT_ERR_CREATE_SIGN)。

实录输出:

Signature ok
subject=/C=CN/O=openHiTLS/OU=TestSign/CN=TLCP_Server
Getting CA Private Key
Generating SM2 signature with userid=1234567812345678
Certificate Version: 3 (0x02)
Extensions added: BasicConstraints, KeyUsage
Certificate generated successfully

6.4 生成服务端加密证书和私钥

# 1. 生成服务端加密私钥
/home/kali/M/openhitls_7287/build/hitls genpkey -algorithm EC \
&nbsp; &nbsp; -pkeyopt&nbsp;"ec_paramgen_curve:sm2"&nbsp;-out server_enc.key

# 2. 生成 CSR
/home/kali/M/openhitls_7287/build/hitls req -new -key server_enc.key \
&nbsp; &nbsp; -subj&nbsp;"/C=CN/O=openHiTLS/OU=TestEnc/CN=TLCP_Server"&nbsp;\
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-out server_enc.csr

# 3. CA 签发服务端加密证书
/home/kali/M/openhitls_7287/build/hitls x509 -req -in&nbsp;server_enc.csr \
&nbsp; &nbsp; -CA ca.crt -CAkey ca.key -days 365 \
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-md sm3 \
&nbsp; &nbsp; -extfile openssl_ext.cnf -extensions server_enc \
&nbsp; &nbsp; -out server_enc.crt

6.5 生成客户端签名/加密证书(用于双向鉴别)

# 客户端签名证书
/home/kali/M/openhitls_7287/build/hitls genpkey -algorithm EC \
&nbsp; &nbsp; -pkeyopt&nbsp;"ec_paramgen_curve:sm2"&nbsp;-out client_sign.key

/home/kali/M/openhitls_7287/build/hitls req -new -key client_sign.key \
&nbsp; &nbsp; -subj&nbsp;"/C=CN/O=openHiTLS/OU=TestSign/CN=TLCP_Client"&nbsp;\
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-out client_sign.csr

/home/kali/M/openhitls_7287/build/hitls x509 -req -in&nbsp;client_sign.csr \
&nbsp; &nbsp; -CA ca.crt -CAkey ca.key -days 365 \
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-md sm3 \
&nbsp; &nbsp; -extfile openssl_ext.cnf -extensions client_sign \
&nbsp; &nbsp; -out client_sign.crt

# 客户端加密证书
/home/kali/M/openhitls_7287/build/hitls genpkey -algorithm EC \
&nbsp; &nbsp; -pkeyopt&nbsp;"ec_paramgen_curve:sm2"&nbsp;-out client_enc.key

/home/kali/M/openhitls_7287/build/hitls req -new -key client_enc.key \
&nbsp; &nbsp; -subj&nbsp;"/C=CN/O=openHiTLS/OU=TestEnc/CN=TLCP_Client"&nbsp;\
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-out client_enc.csr

/home/kali/M/openhitls_7287/build/hitls x509 -req -in&nbsp;client_enc.csr \
&nbsp; &nbsp; -CA ca.crt -CAkey ca.key -days 365 \
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-md sm3 \
&nbsp; &nbsp; -extfile openssl_ext.cnf -extensions client_enc \
&nbsp; &nbsp; -out client_enc.crt

6.6 证书验证

# 验证证书版本和扩展属性
/home/kali/M/openhitls_7287/build/hitls x509 -in&nbsp;server_sign.crt -text -noout |&nbsp;head&nbsp;-25

实录输出(Version 3 + KeyUsage 扩展):

Certificate:
&nbsp; &nbsp; Data:
&nbsp; &nbsp; &nbsp; &nbsp; Version: 3 (0x02)
&nbsp; &nbsp; &nbsp; &nbsp; Serial Number: 4097 (0x1001)
&nbsp; &nbsp; &nbsp; &nbsp; Signature Algorithm: SM2DSAWITHSM3
&nbsp; &nbsp; &nbsp; &nbsp; Issuer: C = CN, O = openHiTLS, OU = TestCA, CN = RootCA
&nbsp; &nbsp; &nbsp; &nbsp; Validity
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Not Before: Jul &nbsp;4 11:18:43 2026 GMT
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Not After : Jul &nbsp;4 11:18:43 2027 GMT
&nbsp; &nbsp; &nbsp; &nbsp; Subject: C = CN, O = openHiTLS, OU = TestSign, CN = TLCP_Server
&nbsp; &nbsp; &nbsp; &nbsp; Subject Public Key Info:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Public Key Algorithm: id-ecPublicKey
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Public-Key: (256 bit)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Pub:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 04:a4:92:92:43:ba:c6:82:bf:34:f5:cc:ac:52:42:fa
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ...
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ANS1 OID: SM2PRIME256
&nbsp; &nbsp; &nbsp; &nbsp; X509V3 extensions:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BasicConstraints:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CA:FALSE
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; KeyUsage: critical
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Digital Signature, Certificate Sign, CRL Sign
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SubjectKeyIdentifier:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; b6:46:87:e1:26:c8:69:fd:25:96:5b:7e:c9:28:58:da:dc:e6:a1:d3
&nbsp; &nbsp; Signature Algorithm: SM2DSAWITHSM3
&nbsp; &nbsp; Signature Value:
&nbsp; &nbsp; &nbsp; &nbsp; 30:46:02:21:00:ef:af:f0:8a:8b:9e:e4:c3:99:6c:cd...
# 验证加密证书
/home/kali/M/openhitls_7287/build/hitls x509 -in&nbsp;server_enc.crt -text -noout | grep -A5&nbsp;"X509V3"

预期输出:

&nbsp; &nbsp; &nbsp; &nbsp; X509V3 extensions:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; BasicConstraints:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; CA:FALSE
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; KeyUsage: critical
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Key Encipherment, Data Encipherment

6.7 Version 1 vs Version 3 证书对比

| 属性 | Version 1 证书 | Version 3 证书 | | — | — | — | | 生成方式 | hitls x509 -req (不加 -extfile) | hitls x509 -req -extfile openssl_ext.cnf -extensions server_sign | | userid 设置 | ✓ 已设置 | ✓ 已设置 | | KeyUsage 扩展 | ✗ 缺失 | ✓ 正确配置 | | BasicConstraints | ✗ 缺失 | ✓ CA:FALSE | | TLCP 握手结果 | ✗ 失败 (0x20c001fHITLS_CERT_ERR_CREATE_SIGN) | ✓ 成功 |

教训: 仅设置 userid 不足以保证自定义证书可用。SM2 双证书体系要求签名证书具有 digitalSignature的 KeyUsage 扩展,加密证书需要keyEncipherment, dataEncipherment的 KeyUsage 扩展。这些扩展属性通过 -extfile+-extensions参数注入。实际openssl_ext.cnf中签名证书还包含keyCertSign, cRLSign(CA 级 KeyUsage,非端实体证书标准要求但 hitls 可接受)和subjectKeyIdentifier = hash(可选扩展),加密证书使用critical标记确保 KeyUsage 被强制执行。

6.8 生成产物清单

/home/kali/M/custom_certs/
├── ca.crt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 根 CA 证书 (userid=1234567812345678)
├── ca.key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 根 CA 私钥 (纯PKCS&nbsp;#8)
├── ca.csr &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # CA 证书签名请求
├── server_sign.key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 服务端签名私钥 (纯PKCS&nbsp;#8)
├── server_sign.csr &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 服务端签名 CSR
├── server_sign.crt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 服务端签名证书 (v3, userid 已设置)
├── server_enc.key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 服务端加密私钥 (纯PKCS&nbsp;#8)
├── server_enc.csr &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 服务端加密 CSR
├── server_enc.crt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 服务端加密证书 (v3, userid 已设置)
├── client_sign.key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 客户端签名私钥 (纯PKCS&nbsp;#8)
├── client_sign.csr &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 客户端签名 CSR
├── client_sign.crt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 客户端签名证书 (v3, userid 已设置)
├── client_enc.key &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 客户端加密私钥 (纯PKCS&nbsp;#8)
├── client_enc.csr &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 客户端加密 CSR
├── client_enc.crt &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # 客户端加密证书 (v3, userid 已设置)
└── openssl_ext.cnf &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;# 扩展配置文件 (5个section)

6.9 hitls vs OpenSSL 对比

| 功能 | hitls (本文档使用) | OpenSSL (旧方案) | | — | — | — | | SM2 私钥生成 | hitls genpkey -algorithm EC -pkeyopt "ec_paramgen_curve:sm2" | openssl ecparam -name SM2 -genkey | | 私钥输出格式 | 纯 PKCS #8,无需过滤 | 包含 EC PARAMETERS 块,需 awk 过滤 | | userid 设置 | 原生支持 -userid "1234567812345678" | 不支持(需额外配置 SM2 userid OID) | | Version 3 扩展 | -extfile openssl_ext.cnf -extensions server_sign | -extfile xxx.conf -extensions v3_req | | SM3 签名 | -md sm3 | -sm3 | | 证书验证 | hitls verify -CAfile ca.crt -nokeyusage server_sign.crt | openssl verify -CAfile ca.pem cert.pem |

结论4c147a49 commit 之后,hitls 已完全取代 OpenSSL 用于 SM2 证书生成。生成的证书经实测验证,在所有 TLCP/DTLCP 密码套件(ECDHE/ECC × CBC/GCM)的双向和单向鉴别场景下均工作正常。


七、测试一:TLCP + ECDHE_SM4_CBC_SM3 + 双向鉴别

预期:握手成功。双方均提供双证书,ECDHE 密钥交换正常。

命名说明:以下手动测试章节使用描述性 pcap 文件名(如 tlcp_ecdhe_two_way.pcap)。自动化测试脚本 run_all_tests.sh 使用带 custom_/builtin_ 前缀的命名(如 custom_tlcp_ecdhe_cbc_two_way.pcap)。两种命名对应同一测试场景,实际交付的 32 个 pcap 文件使用自动化脚本命名(详见 §25.1)。

7.1 服务端(终端1)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_CBC_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_CBC_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Listening on 127.0.0.1:4433 (TCP)
Server started, waiting for connections...
Accepted connection from 127.0.0.1:<ephemeral_port>
STATE: SSL negotiation finished successfully
STATE: SSL negotiation finished successfully

服务端调用 -state 打印握手状态。连接建立后服务端进入交互模式,等待客户端发送数据。握手成功后会在终端输出协议版本、协商密码套件、握手状态等信息。实际输出中 STATE: SSL negotiation finished successfully 可能出现两次(对应握手的不同阶段状态转换)。

7.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/tlcp_ecdhe_two_way.pcap port 4433

输出: tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes

7.3 客户端(终端2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;|&nbsp;timeout&nbsp;10 /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECDHE_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECDHE_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Connected to 127.0.0.1:4433
Starting TLS handshake...
STATE: SSL negotiation finished successfully
STATE: SSL negotiation finished successfully
TLS handshake completed successfully
Protocol version: TLCP v1.1
Cipher suite negotiated: TLS_ECDHE_SM4_CBC_SM3
Handshake state: connected

注意:客户端输出中 STATE: SSL negotiation finished successfully 可能出现两次(对应握手的不同阶段状态转换)。hitls 客户端在握手成功后自动进入交互模式,可通过管道发送”利刃信安”等测试数据。客户端工具内部对收到的应用层数据做格式化封装显示,并非服务端返回了 HTTP 响应。

7.4 停止与验证

# 服务端: Ctrl+C 或 pkill
sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/tlcp_ecdhe_two_way.pcap
-rw-r--r-- 1 tcpdump tcpdump 4.0K Jul &nbsp;4 10:30 &nbsp;tlcp_ecdhe_two_way.pcap

结果: 成功。15 packets, 4.0K。

消息序列:

&nbsp;1-3 &nbsp; TCP 三次握手
&nbsp;4 &nbsp; &nbsp; ClientHello (含 ECDHE_SM4_CBC_SM3)
&nbsp;5 &nbsp; &nbsp; ServerHello
&nbsp;6 &nbsp; &nbsp; Certificate (服务端双证书)
&nbsp;7 &nbsp; &nbsp; ServerKeyExchange (ECDHE 公钥+SM2 签名)
&nbsp;8 &nbsp; &nbsp; CertificateRequest (ECDHE 强制)
&nbsp;9 &nbsp; &nbsp; ServerHelloDone
10 &nbsp; &nbsp; Certificate (客户端双证书)
11 &nbsp; &nbsp; ClientKeyExchange (SM2加密premaster key)
12 &nbsp; &nbsp; [CCS]+Finished (客户端)
13 &nbsp; &nbsp; [CCS]+Finished (服务端)
14 &nbsp; &nbsp; 加密应用数据

八、测试二:TLCP + ECDHE_SM4_CBC_SM3 + 单向鉴别

预期:握手失败。ECDHE 强制 CertificateRequest,客户端无加密证书 → 0x20c0029。

8.1 服务端(终端1,-noverify)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_CBC_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state -noverify

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_CBC_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state -noverify

输出:

Listening on 127.0.0.1:4433 (TCP)
Server started, waiting for connections...
TLS handshake failed: 0x2040017
Failed to handle client connection

8.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/tlcp_ecdhe_one_way.pcap port 4433

输出: tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes

8.3 客户端(终端2,无客户端证书)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECDHE_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECDHE_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -provider default -state

客户端不传 -tlcp_sign_cert/sign_key/enc_cert/enc_key,模拟单向鉴别——仅具有验证服务端证书的 CA 根证书,无自身证书。

输出:

Connected to 127.0.0.1:4433
Starting TLS handshake...
client: TLS handshake failed: 0x20c0029
client: Failed to create config and connection: 0x27

8.4 错误码对照

| 端点 | 错误码 | 宏名称 | 含义 | 源码位置 | | — | — | — | — | — | | 客户端 | 0x20c0029 | HITLS_CERT_ERR_ENCODE | Failed to encode the certificate | parse_server_key_exchange.c L497 | | 服务端 | 0x2040017 | HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE | Not receive the peer certificate | recv_certificate.c L350 |

8.5 失败路径消息序列

&nbsp;1-3 &nbsp; TCP 三次握手
&nbsp;4 &nbsp; &nbsp; ClientHello (ECDHE_SM4_CBC_SM3)
&nbsp;5 &nbsp; &nbsp; ServerHello (确认密码套件)
&nbsp;6 &nbsp; &nbsp; Certificate (服务端双证书)
&nbsp;7 &nbsp; &nbsp; ServerKeyExchange (ECDHE 公钥 + SM2 签名)
&nbsp;8 &nbsp; &nbsp; CertificateRequest &nbsp; &nbsp; &nbsp;← 虽然 -noverify,ECDHE 仍强制发送 (§4.2 L305-310)
&nbsp;9 &nbsp; &nbsp; ServerHelloDone
&nbsp; &nbsp; &nbsp; &nbsp;客户端解析 ServerKeyExchange 以验证服务端 SM2 签名
&nbsp; &nbsp; &nbsp; &nbsp;→ parse_server_key_exchange.c:495: SAL_CERT_ClntGmEncodeEncCert()
&nbsp; &nbsp; &nbsp; &nbsp;→ cert.c:736: EncodeEncCert(ctx, peerCert->encCert, useLen)
&nbsp; &nbsp; &nbsp; &nbsp;→ cert.c:679: peerCert->encCert == NULL → return NULL
&nbsp; &nbsp; &nbsp; &nbsp;→ parse_server_key_exchange.c:497: HITLS_CERT_ERR_ENCODE (0x20c0029)
10 &nbsp; &nbsp; Alert (Fatal) → 服务端
&nbsp; &nbsp; &nbsp; &nbsp;服务端收到 Alert → recv_certificate.c:350: 0x2040017

8.6 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/tlcp_ecdhe_one_way.pcap
-rw-r--r-- 1 tcpdump tcpdump 2.3K ... tlcp_ecdhe_one_way.pcap

结果: 失败(预期内)。10 packets, 2.3K。


九、测试三:TLCP + ECC_SM4_CBC_SM3 + 双向鉴别

预期:握手成功。ECC 密钥交换,双证书双向验证。

9.1 服务端(终端1)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_CBC_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_CBC_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Listening on 127.0.0.1:4433 (TCP)
Server started, waiting for connections...

9.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/tlcp_ecc_two_way.pcap port 4433

9.3 客户端(终端2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECC_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECC_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Connected to 127.0.0.1:4433
Starting TLS handshake...
TLS handshake completed successfully
Protocol version: TLCP v1.1
Cipher suite negotiated: TLS_ECC_SM4_CBC_SM3
Handshake state: connected

握手成功后,hitls 客户端进入交互模式。通过管道发送的测试数据”利刃信安”被服务端接收并回显。客户端工具内部对收到的应用层数据做格式化封装显示。

消息序列:

&nbsp;1-3 &nbsp; TCP 三次握手
&nbsp;4 &nbsp; &nbsp; ClientHello (含 ECC_SM4_CBC_SM3)
&nbsp;5 &nbsp; &nbsp; ServerHello
&nbsp;6 &nbsp; &nbsp; Certificate (服务端双证书)
&nbsp;7 &nbsp; &nbsp; ServerKeyExchange (ECC: 服务端签名)
&nbsp;8 &nbsp; &nbsp; CertificateRequest (双向验证请求)
&nbsp;9 &nbsp; &nbsp; ServerHelloDone
10 &nbsp; &nbsp; Certificate (客户端双证书)
11 &nbsp; &nbsp; ClientKeyExchange (SM2加密premaster key)
12 &nbsp; &nbsp; [CCS]+Finished (客户端)
13 &nbsp; &nbsp; [CCS]+Finished (服务端)
14 &nbsp; &nbsp; 加密应用数据

9.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/tlcp_ecc_two_way.pcap
-rw-r--r-- 1 tcpdump tcpdump 4.0K ... tlcp_ecc_two_way.pcap

结果: 成功。14 packets, 4.0K。


十、测试四:TLCP + ECC_SM4_CBC_SM3 + 单向鉴别

预期:握手成功。真正单向鉴别——服务端不验证客户端身份,ECC 不强制客户端证书。

原理: ECC 的 kxAlg=HITLS_KEY_EXCH_ECC,不满足 send_server_key_exchange.c L307 条件,直接跳 L311 发送 ServerHelloDone。 -noverify 关闭证书验证。

10.1 服务端(终端1,-noverify)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_CBC_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state -noverify

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_CBC_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state -noverify

输出:

Listening on 127.0.0.1:4433 (TCP)
Server started, waiting for connections...

10.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/tlcp_ecc_one_way.pcap port 4433

10.3 客户端(终端2,无客户端证书)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECC_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECC_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -provider default -state

输出:

Connected to 127.0.0.1:4433
Starting TLS handshake...
TLS handshake completed successfully
Protocol version: TLCP v1.1
Cipher suite negotiated: TLS_ECC_SM4_CBC_SM3
Handshake state: connected

握手成功后,hitls 客户端进入交互模式。通过管道发送的测试数据”利刃信安”被服务端接收并回显。客户端工具内部对收到的应用层数据做格式化封装显示。

消息序列(无 CertificateRequest + 无客户端 Certificate):

&nbsp;1-3 &nbsp; TCP 三次握手
&nbsp;4 &nbsp; &nbsp; ClientHello
&nbsp;5 &nbsp; &nbsp; ServerHello
&nbsp;6 &nbsp; &nbsp; Certificate (服务端双证书)
&nbsp;7 &nbsp; &nbsp; ServerKeyExchange
&nbsp;8 &nbsp; &nbsp; ServerHelloDone &nbsp; &nbsp; &nbsp;← 注意: 无 CertificateRequest!
&nbsp;9 &nbsp; &nbsp; ClientKeyExchange &nbsp; &nbsp;← SM2 用服务端加密公钥加密 premaster key
10 &nbsp; &nbsp; [CCS]+Finished (客户端)
11 &nbsp; &nbsp; [CCS]+Finished (服务端)
12 &nbsp; &nbsp; 加密应用数据

注: 消息序列共 12 条逻辑消息,pcap 中实际为 16 packets(多出 4 个 TCP ACK)。

10.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/tlcp_ecc_one_way.pcap
-rw-r--r-- 1 tcpdump tcpdump 3.0K ... tlcp_ecc_one_way.pcap

结果: 成功。16 packets, 3.0K。


十一、测试五:DTLCP + ECDHE_SM4_CBC_SM3 + 双向鉴别

DTLCP = TLCP over UDP。握手消息含序号和分片偏移量。协议版本标识为 “DTLCP v1.1″。

11.1 服务端(终端1,端口 4444)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4444 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_CBC_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4444 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_CBC_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

11.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/dtlcp_ecdhe_two_way.pcap port 4444

11.3 客户端(终端2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4444 -cipher TLS_ECDHE_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4444 -cipher TLS_ECDHE_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出: 握手成功。UDP 无三次握手,Certificate 超过 MTU 时分片。

消息序列:

ClientHello ──(握手)──▶ ServerHello, Certificate*, ServerKeyExchange, CertificateRequest, ServerHelloDone
ClientCertificate*, ClientKeyExchange, CertificateVerify, [ChangeCipherSpec], Finished ──▶
◀── [ChangeCipherSpec], Finished
─────── 应用数据 ────────

与 TLCP 版本的区别:DTLCP 基于 UDP,无 TCP 三次握手。证书消息可能通过 handshake_fragment 分片传输(超过 MTU 时)。

11.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/dtlcp_ecdhe_two_way.pcap
-rw-r--r-- 1 tcpdump tcpdump 3.5K ... dtlcp_ecdhe_two_way.pcap

结果: 成功。8 packets, 3.5K。


十二、测试六:DTLCP + ECDHE_SM4_CBC_SM3 + 单向鉴别

预期:失败。与 TLCP ECDHE 单向相同根因。

12.1 服务端(终端1,-noverify,端口 4444)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4444 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_CBC_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state -noverify

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4444 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_CBC_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state -noverify

输出: TLS handshake failed: 0x2040017

12.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/dtlcp_ecdhe_one_way.pcap port 4444

12.3 客户端(终端2,无证书)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4444 -cipher TLS_ECDHE_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4444 -cipher TLS_ECDHE_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -provider default -state

输出: TLS handshake failed: 0x20c0029

12.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/dtlcp_ecdhe_one_way.pcap
-rw-r--r-- 1 tcpdump tcpdump 1.8K ... dtlcp_ecdhe_one_way.pcap

结果: 失败。4 packets, 1.8K。UDP 无三次握手,总包数少于 TCP 场景。


十三、测试七:DTLCP + ECC_SM4_CBC_SM3 + 双向鉴别

13.1 服务端(终端1,端口 4445)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4445 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_CBC_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4445 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_CBC_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Listening on 127.0.0.1:4445 (UDP)
Server started, waiting for connections...

13.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/dtlcp_ecc_two_way.pcap port 4445

13.3 客户端(终端2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4445 -cipher TLS_ECC_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4445 -cipher TLS_ECC_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出: 握手成功。UDP 无三次握手,Certificate 超过 MTU 时分片。

消息序列:

ClientHello ──(握手)──▶ ServerHello, Certificate*, ServerKeyExchange, ServerHelloDone
ClientCertificate*, ClientKeyExchange, CertificateVerify, [ChangeCipherSpec], Finished ──▶
◀── [ChangeCipherSpec], Finished
─────── 应用数据 ────────

ECC 无 CertificateRequest,但双向鉴别仍需客户端提供双证书。DTLCP 握手消息可能分片。

13.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/dtlcp_ecc_two_way.pcap
-rw-r--r-- 1 tcpdump tcpdump 3.5K ... dtlcp_ecc_two_way.pcap

结果: 成功。8 packets, 3.5K。


十四、测试八:DTLCP + ECC_SM4_CBC_SM3 + 单向鉴别

14.1 服务端(终端1,-noverify,端口 4445)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4445 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_CBC_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state -noverify

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4445 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_CBC_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state -noverify

输出:

Listening on 127.0.0.1:4445 (UDP)
Server started, waiting for connections...

14.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/dtlcp_ecc_one_way.pcap port 4445

14.3 客户端(终端2,无证书)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4445 -cipher TLS_ECC_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4445 -cipher TLS_ECC_SM4_CBC_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -provider default -state

输出: 握手成功。UDP 无三次握手,单向鉴别无需客户端证书。

14.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/dtlcp_ecc_one_way.pcap
-rw-r--r-- 1 tcpdump tcpdump 2.5K ... dtlcp_ecc_one_way.pcap

结果: 成功。8 packets, 2.5K。


十五、GCM 密码套件

15.1 GCM 与 CBC 的关系

GCM 密码套件(ECDHE_SM4_GCM_SM3ECC_SM4_GCM_SM3)与 CBC 套件共享相同的密钥交换算法:

| 密码套件 | 内部 kxAlg | 加密模式 | | — | — | — | | TLS_ECDHE_SM4_CBC_SM3 | HITLS_KEY_EXCH_ECDHE | CBC | | TLS_ECDHE_SM4_GCM_SM3 | HITLS_KEY_EXCH_ECDHE | GCM | | TLS_ECC_SM4_CBC_SM3 | HITLS_KEY_EXCH_ECC | CBC | | TLS_ECC_SM4_GCM_SM3 | HITLS_KEY_EXCH_ECC | GCM |

GCM 仅改变 AEAD 加密模式(SM4 在 GCM 模式下的认证加密 vs 传统 CBC 模式),不改变密钥交换算法。因此 send_server_key_exchange.c L307 的 kxAlg==ECDHE 判断对 GCM 同样生效。以下 8 个测试(测试九~~十六,见第十六~~二十三章)的结果与 CBC 对应测试完全一致。

15.2 端口规划

以下端口在 CBC 和 GCM 测试中共用。每次测试前需确保前一测试的服务端已停止(sudo pkill -f "hitls s_server"),避免端口占用。

| 端口 | 协议 | 测试 | | — | — | — | | 4433 | TCP | 测试一到四(TLCP CBC)、测试九~十二(TLCP GCM) | | 4444 | UDP | 测试五~~六(DTLCP ECDHE CBC)、测试十三~~十四(DTLCP ECDHE GCM) | | 4445 | UDP | 测试七~~八(DTLCP ECC CBC)、测试十五~~十六(DTLCP ECC GCM) |

注意:每次测试前需确保前一测试的服务端已停止(sudo pkill -f "hitls s_server"),避免端口占用。


十六、测试九:TLCP + ECDHE_SM4_GCM_SM3 + 双向鉴别

预期:握手成功。双方均提供双证书,ECDHE 密钥交换正常。

16.1 服务端(终端1)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_GCM_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_GCM_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Listening on 127.0.0.1:4433 (TCP)
Server started, waiting for connections...

16.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/tlcp_ecdhe_gcm_two_way.pcap port 4433

输出: tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes

16.3 客户端(终端2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECDHE_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECDHE_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Connected to 127.0.0.1:4433
Starting TLS handshake...
TLS handshake completed successfully
Protocol version: TLCP v1.1
Cipher suite negotiated: TLS_ECDHE_SM4_GCM_SM3
Handshake state: connected

GCM 套件与 CBC 套件的客户端输出格式完全一致。握手成功后 hitls 客户端进入交互模式,通过管道发送的测试数据”利刃信安” 被服务端接收并回显。客户端工具内部对收到的应用层数据做格式化封装显示。

16.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/tlcp_ecdhe_gcm_two_way.pcap

结果: 成功。14 packets, 3.7K。tlcp_ecdhe_gcm_two_way.pcap


十七、测试十:TLCP + ECDHE_SM4_GCM_SM3 + 单向鉴别

预期:握手失败。ECDHE 强制 CertificateRequest,客户端无加密证书 → 服务端 0x2040017,客户端 0x20c0029。与 CBC 版本根因相同。

17.1 服务端(终端1,-noverify)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_GCM_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state -noverify

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_GCM_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state -noverify

输出:

Listening on 127.0.0.1:4433 (TCP)
Server started, waiting for connections...
TLS handshake failed: 0x2040017
Failed to handle client connection

17.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/tlcp_ecdhe_gcm_one_way.pcap port 4433

输出: tcpdump: listening on lo, link-type EN10MB (Ethernet), snapshot length 262144 bytes

17.3 客户端(终端2,无客户端证书)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECDHE_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECDHE_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -provider default -state

客户端不传 -tlcp_sign_cert/sign_key/enc_cert/enc_key,模拟单向鉴别——仅具有验证服务端证书的 CA 根证书,无自身证书。

输出:

Connected to 127.0.0.1:4433
Starting TLS handshake...
client: TLS handshake failed: 0x20c0029
client: Failed to create config and connection: 0x27

17.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/tlcp_ecdhe_gcm_one_way.pcap

结果: 失败(预期内)。10 packets, 2.2K。tlcp_ecdhe_gcm_one_way.pcap


十八、测试十一:TLCP + ECC_SM4_GCM_SM3 + 双向鉴别

预期:握手成功。ECC 密钥交换,双证书双向验证。

18.1 服务端(终端1)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_GCM_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_GCM_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Listening on 127.0.0.1:4433 (TCP)
Server started, waiting for connections...

18.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/tlcp_ecc_gcm_two_way.pcap port 4433

18.3 客户端(终端2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECC_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECC_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Connected to 127.0.0.1:4433
Starting TLS handshake...
TLS handshake completed successfully
Protocol version: TLCP v1.1
Cipher suite negotiated: TLS_ECC_SM4_GCM_SM3
Handshake state: connected

握手成功后 hitls 客户端进入交互模式,通过管道发送的测试数据”利刃信安”被服务端接收并回显。客户端工具内部对收到的应用层数据做格式化封装显示。

18.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/tlcp_ecc_gcm_two_way.pcap

结果: 成功。14 packets, 3.7K。tlcp_ecc_gcm_two_way.pcap


十九、测试十二:TLCP + ECC_SM4_GCM_SM3 + 单向鉴别

预期:握手成功。真正单向鉴别——服务端不验证客户端身份,ECC 不强制客户端证书。与 CBC 版本一致。

19.1 服务端(终端1,-noverify)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_GCM_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state -noverify

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -tlcp -accept 127.0.0.1:4433 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_GCM_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state -noverify

19.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/tlcp_ecc_gcm_one_way.pcap port 4433

19.3 客户端(终端2,无客户端证书)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECC_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -tlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4433 -cipher TLS_ECC_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -provider default -state

输出:

Connected to 127.0.0.1:4433
Starting TLS handshake...
TLS handshake completed successfully
Protocol version: TLCP v1.1
Cipher suite negotiated: TLS_ECC_SM4_GCM_SM3
Handshake state: connected

握手成功后 hitls 客户端进入交互模式,通过管道发送的测试数据”利刃信安”被服务端接收并回显。客户端工具内部对收到的应用层数据做格式化封装显示。

19.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/tlcp_ecc_gcm_one_way.pcap

结果: 成功。14 packets, 2.9K。tlcp_ecc_gcm_one_way.pcap


二十、测试十三:DTLCP + ECDHE_SM4_GCM_SM3 + 双向鉴别

DTLCP = TLCP over UDP。握手消息含序号和分片偏移量。协议版本标识为 “DTLCP v1.1″。

20.1 服务端(终端1,端口 4444)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4444 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_GCM_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4444 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_GCM_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

20.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/dtlcp_ecdhe_gcm_two_way.pcap port 4444

20.3 客户端(终端2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4444 -cipher TLS_ECDHE_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4444 -cipher TLS_ECDHE_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

输出:

Listening on 127.0.0.1:4444 (UDP)
Server started, waiting for connections...
TLS handshake completed successfully

客户端输出:

Connected to 127.0.0.1:4444
Starting TLS handshake...
TLS handshake completed successfully
Protocol version: DTLCP v1.1
Cipher suite negotiated: TLS_ECDHE_SM4_GCM_SM3
Handshake state: connected

20.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/dtlcp_ecdhe_gcm_two_way.pcap

结果: 成功。8 packets, 3.3K。dtlcp_ecdhe_gcm_two_way.pcap


二十一、测试十四:DTLCP + ECDHE_SM4_GCM_SM3 + 单向鉴别

预期:失败。与 TLCP ECDHE 单向相同根因。

21.1 服务端(终端1,-noverify,端口 4444)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4444 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_GCM_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state -noverify

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4444 \
&nbsp; &nbsp; -cipher TLS_ECDHE_SM4_GCM_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state -noverify

输出:

Listening on 127.0.0.1:4444 (UDP)
Server started, waiting for connections...
TLS handshake failed: 0x2040017

21.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/dtlcp_ecdhe_gcm_one_way.pcap port 4444

21.3 客户端(终端2,无证书)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4444 -cipher TLS_ECDHE_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4444 -cipher TLS_ECDHE_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -provider default -state

输出:

Connected to 127.0.0.1:4444
Starting TLS handshake...
TLS handshake failed: 0x20c0029

21.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/dtlcp_ecdhe_gcm_one_way.pcap

结果: 失败(预期内)。4 packets, 1.8K。dtlcp_ecdhe_gcm_one_way.pcap


二十二、测试十五:DTLCP + ECC_SM4_GCM_SM3 + 双向鉴别

22.1 服务端(终端1,端口 4445)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4445 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_GCM_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4445 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_GCM_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

22.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/dtlcp_ecc_gcm_two_way.pcap port 4445

22.3 客户端(终端2)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4445 -cipher TLS_ECC_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4445 -cipher TLS_ECC_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state

22.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/dtlcp_ecc_gcm_two_way.pcap

结果: 成功。8 packets, 3.3K。dtlcp_ecc_gcm_two_way.pcap


二十三、测试十六:DTLCP + ECC_SM4_GCM_SM3 + 单向鉴别

23.1 服务端(终端1,-noverify,端口 4445)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4445 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_GCM_SM3 -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key \
&nbsp; &nbsp; -provider default -state -noverify

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
/home/kali/M/openhitls_7287/build/hitls s_server -dtlcp -accept 127.0.0.1:4445 \
&nbsp; &nbsp; -cipher TLS_ECC_SM4_GCM_SM3 -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -tlcp_sign_cert&nbsp;$C/sign.crt -tlcp_sign_key&nbsp;$C/sign.key \
&nbsp; &nbsp; -tlcp_enc_cert&nbsp;$C/enc.crt -tlcp_enc_key&nbsp;$C/enc.key \
&nbsp; &nbsp; -provider default -state -noverify

23.2 抓包(终端3)

sudo&nbsp;tcpdump -i lo -w /home/kali/M/captures/dtlcp_ecc_gcm_one_way.pcap port 4445

23.3 客户端(终端2,无证书)

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
CUSTOM_CERT=/home/kali/M/custom_certs
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4445 -cipher TLS_ECC_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$CUSTOM_CERT/ca.crt \
&nbsp; &nbsp; -provider default -state

若方案A握手失败,改用源码内置证书(方案B):

export&nbsp;LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH
C=/home/kali/M/openhitls_7287/testcode/testdata/tls/certificate/der/sm2_with_userid
echo&nbsp;"利刃信安"&nbsp;| /home/kali/M/openhitls_7287/build/hitls s_client -dtlcp \
&nbsp; &nbsp; -host 127.0.0.1 -port 4445 -cipher TLS_ECC_SM4_GCM_SM3 \
&nbsp; &nbsp; -CAfile&nbsp;$C/ca.crt -chainCAfile&nbsp;$C/inter.crt \
&nbsp; &nbsp; -provider default -state

23.4 停止与验证

sudo&nbsp;pkill -f&nbsp;"hitls s_server"
# 终端3 tcpdump: Ctrl+C 停止抓包

$&nbsp;ls&nbsp;-lh captures/dtlcp_ecc_gcm_one_way.pcap

结果: 成功。8 packets, 2.3K。dtlcp_ecc_gcm_one_way.pcap


二十四、IBC 密码套件不支持说明

24.1 结论

IBC_SM4_CBC_SM3 和 IBC_SM4_GCM_SM3 在 openhitls-0.3 分支中不支持

24.2 证据

对 openhitls-0.3 全量源码进行检索:

# 搜索 IBC 相关宏
$ grep -r&nbsp;"IBC"&nbsp;/home/kali/M/openhitls_7287/config/macro_config/ --include="*.h"
# 无匹配结果

# 搜索 IBC 密码套件定义
$ grep -r&nbsp;"IBC_SM4"&nbsp;/home/kali/M/openhitls_7287/tls/ --include="*.c"
# 无匹配结果

# 搜索 HITLS_TLS_SUITE_IBC
$ grep -r&nbsp;"HITLS_TLS_SUITE_IBC"&nbsp;/home/kali/M/openhitls_7287/ --include="*.h"&nbsp;--include="*.c"
# 无匹配结果

源码中不存在任何 IBC 或 HITLS_TLS_SUITE_IBC 宏定义,cipher_suite.c 中也无 IBC 相关密码套件注册。

24.3 技术背景

IBC(Identity-Based Cryptography,基于标识的密码学)基于 SM9 标识密码算法。openhitls-0.3 分支虽有 SM9 底层密码学支持( HITLS_CRYPTO_SM9 宏),但该支持仅限于 crypto 层,并未扩展到 TLS 密码套件层。如需 IBC SM4 密码套件支持,可能需要更高版本的 openHiTLS 分支(如 openhitls-0.4 或 master)。


二十五、交付总览

25.1 32 个 pcap 文件(实际交付)

实际测试产生了 32 个 pcap 文件(16 个自定义证书 + 16 个内置证书)。以下为 ls -lh 实录输出:

/home/kali/M/captures/
自定义证书 (custom_, 16 个):
├── custom_tlcp_ecdhe_cbc_two_way.pcap &nbsp; (4.0K) &nbsp;TLCP+ECDHE_CBC+双向 &nbsp;→ 成功
├── custom_tlcp_ecdhe_cbc_one_way.pcap &nbsp; (2.3K) &nbsp;TLCP+ECDHE_CBC+单向 &nbsp;→ 失败(0x20c0029)
├── custom_tlcp_ecc_cbc_two_way.pcap &nbsp; &nbsp; (4.0K) &nbsp;TLCP+ECC_CBC+双向 &nbsp; &nbsp;→ 成功
├── custom_tlcp_ecc_cbc_one_way.pcap &nbsp; &nbsp; (3.0K) &nbsp;TLCP+ECC_CBC+单向 &nbsp; &nbsp;→ 成功
├── custom_dtlcp_ecdhe_cbc_two_way.pcap &nbsp;(3.5K) &nbsp;DTLCP+ECDHE_CBC+双向 → 成功
├── custom_dtlcp_ecdhe_cbc_one_way.pcap &nbsp;(1.8K) &nbsp;DTLCP+ECDHE_CBC+单向 → 失败(0x20c0029)
├── custom_dtlcp_ecc_cbc_two_way.pcap &nbsp; &nbsp;(3.5K) &nbsp;DTLCP+ECC_CBC+双向 &nbsp; → 成功
├── custom_dtlcp_ecc_cbc_one_way.pcap &nbsp; &nbsp;(2.5K) &nbsp;DTLCP+ECC_CBC+单向 &nbsp; → 成功
├── custom_tlcp_ecdhe_gcm_two_way.pcap &nbsp; (3.7K) &nbsp;TLCP+ECDHE_GCM+双向 &nbsp;→ 成功
├── custom_tlcp_ecdhe_gcm_one_way.pcap &nbsp; (2.2K) &nbsp;TLCP+ECDHE_GCM+单向 &nbsp;→ 失败(0x20c0029)
├── custom_tlcp_ecc_gcm_two_way.pcap &nbsp; &nbsp; (3.7K) &nbsp;TLCP+ECC_GCM+双向 &nbsp; &nbsp;→ 成功
├── custom_tlcp_ecc_gcm_one_way.pcap &nbsp; &nbsp; (2.9K) &nbsp;TLCP+ECC_GCM+单向 &nbsp; &nbsp;→ 成功
├── custom_dtlcp_ecdhe_gcm_two_way.pcap &nbsp;(3.3K) &nbsp;DTLCP+ECDHE_GCM+双向 → 成功
├── custom_dtlcp_ecdhe_gcm_one_way.pcap &nbsp;(1.8K) &nbsp;DTLCP+ECDHE_GCM+单向 → 失败(0x20c0029)
├── custom_dtlcp_ecc_gcm_two_way.pcap &nbsp; &nbsp;(3.3K) &nbsp;DTLCP+ECC_GCM+双向 &nbsp; → 成功
└── custom_dtlcp_ecc_gcm_one_way.pcap &nbsp; &nbsp;(2.3K) &nbsp;DTLCP+ECC_GCM+单向 &nbsp; → 成功

源码内置证书 (builtin_, 16 个):
├── builtin_tlcp_ecdhe_cbc_two_way.pcap &nbsp;(5.4K) &nbsp;TLCP+ECDHE_CBC+双向 &nbsp;→ 成功
├── builtin_tlcp_ecdhe_cbc_one_way.pcap &nbsp;(2.9K) &nbsp;TLCP+ECDHE_CBC+单向 &nbsp;→ 失败(0x20c0029)
├── builtin_tlcp_ecc_cbc_two_way.pcap &nbsp; &nbsp;(5.5K) &nbsp;TLCP+ECC_CBC+双向 &nbsp; &nbsp;→ 成功
├── builtin_tlcp_ecc_cbc_one_way.pcap &nbsp; &nbsp;(3.7K) &nbsp;TLCP+ECC_CBC+单向 &nbsp; &nbsp;→ 成功
├── builtin_dtlcp_ecdhe_cbc_two_way.pcap (5.1K) &nbsp;DTLCP+ECDHE_CBC+双向 → 成功
├── builtin_dtlcp_ecdhe_cbc_one_way.pcap (2.6K) &nbsp;DTLCP+ECDHE_CBC+单向 → 失败(0x20c0029)
├── builtin_dtlcp_ecc_cbc_two_way.pcap &nbsp; (5.1K) &nbsp;DTLCP+ECC_CBC+双向 &nbsp; → 成功
├── builtin_dtlcp_ecc_cbc_one_way.pcap &nbsp; (3.3K) &nbsp;DTLCP+ECC_CBC+单向 &nbsp; → 成功
├── builtin_tlcp_ecdhe_gcm_two_way.pcap &nbsp;(5.2K) &nbsp;TLCP+ECDHE_GCM+双向 &nbsp;→ 成功
├── builtin_tlcp_ecdhe_gcm_one_way.pcap &nbsp;(2.9K) &nbsp;TLCP+ECDHE_GCM+单向 &nbsp;→ 失败(0x20c0029)
├── builtin_tlcp_ecc_gcm_two_way.pcap &nbsp; &nbsp;(5.3K) &nbsp;TLCP+ECC_GCM+双向 &nbsp; &nbsp;→ 成功
├── builtin_tlcp_ecc_gcm_one_way.pcap &nbsp; &nbsp;(3.5K) &nbsp;TLCP+ECC_GCM+单向 &nbsp; &nbsp;→ 成功
├── builtin_dtlcp_ecdhe_gcm_two_way.pcap (4.9K) &nbsp;DTLCP+ECDHE_GCM+双向 → 成功
├── builtin_dtlcp_ecdhe_gcm_one_way.pcap (2.6K) &nbsp;DTLCP+ECDHE_GCM+单向 → 失败(0x20c0029)
├── builtin_dtlcp_ecc_gcm_two_way.pcap &nbsp; (4.9K) &nbsp;DTLCP+ECC_GCM+双向 &nbsp; → 成功
└── builtin_dtlcp_ecc_gcm_one_way.pcap &nbsp; (3.1K) &nbsp;DTLCP+ECC_GCM+单向 &nbsp; → 成功

注:内置证书(builtin_)pcap 文件普遍比自定义证书(custom_)大 1-2K,这是因为内置证书使用 sm2_with_userid 目录下的证书(含中间 CA 证书链),证书链更长,Certificate 消息体积更大。两种证书的功能测试结果完全一致。

注:CBC 与 GCM 套件在同一握手场景下 TCP 包数存在 ±1-2 的差异,这是因为 TCP 层 ACK 包的捕获时机受抓包启动时序和网络条件影响,不影响握手逻辑的正确性分析。

25.2 完整结果矩阵

密码套件 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; TLCP (TCP) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;DTLCP (UDP)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;双向 &nbsp; &nbsp;单向 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 双向 &nbsp; &nbsp;单向
─────────────────────────────────────────────────────────
ECDHE_SM4_CBC_SM3 &nbsp; &nbsp; &nbsp;成功 &nbsp; &nbsp;失败(0x20c0029) &nbsp;成功 &nbsp; &nbsp;失败(0x20c0029)
ECC_SM4_CBC_SM3 &nbsp; &nbsp; &nbsp; &nbsp;成功 &nbsp; &nbsp;成功 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;成功 &nbsp; &nbsp;成功
ECDHE_SM4_GCM_SM3 &nbsp; &nbsp; &nbsp;成功 &nbsp; &nbsp;失败(0x20c0029) &nbsp;成功 &nbsp; &nbsp;失败(0x20c0029)
ECC_SM4_GCM_SM3 &nbsp; &nbsp; &nbsp; &nbsp;成功 &nbsp; &nbsp;成功 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;成功 &nbsp; &nbsp;成功

GCM 与 CBC 结果完全一致,验证了 GCM 仅改变 AEAD 加密模式、不改变密钥交换行为的结论。

上述结果矩阵适用于自定义证书和内置证书两种场景。两种证书类型在相同测试条件下结果完全一致,仅 pcap 文件大小不同(内置证书因含中间 CA 证书链,体积更大)。

25.3 端口使用

| 端口 | 协议 | 测试 | | — | — | — | | 4433 | TCP | 测试一到四、九到十二(TLCP) | | 4444 | UDP | 测试五到六、十三到十四(DTLCP+ECDHE) | | 4445 | UDP | 测试七到八、十五到十六(DTLCP+ECC) |

25.4 脚本文件清单

实际交付的脚本文件

  • • /home/kali/M/run_all_tests.sh — 32用例综合自动化脚本(覆盖自定义证书16个 + 内置证书16个),详见 §三十
  • • /home/kali/M/run_tests.sh — 16用例版本(仅自定义证书),详见 §30.1 嵌入代码

实际测试时可直接使用文档中各测试章节的命令行手动执行,无需单独创建脚本文件。以下为实际交付的脚本文件说明:

| 脚本 | 用途 | 是否存在 | | — | — | — | | run_all_tests.sh | 综合自动化脚本(32用例,推荐) | ✓ | | run_tests.sh | 自定义证书16用例脚本 | ✓ |

命名约定: 文档中手动测试章节(§七~§二十三)使用描述性 pcap 文件名(如 tlcp_ecdhe_two_way.pcap),自动化测试脚本( run_all_tests.sh)使用带 custom_/builtin_ 前缀的命名(如 custom_tlcp_ecdhe_cbc_two_way.pcapbuiltin_tlcp_ecdhe_cbc_two_way.pcap)。两种命名体系对应同一组测试场景,实际交付的 32 个 pcap 文件使用自动化脚本命名。


二十六、-noverify 参数完整剖析

26.1 Git 提交

commit ab0d11e1
Author: openHiTLS <[email protected]>
Date: &nbsp; 2025-07-02

&nbsp; &nbsp; fix:The command line parameter "noverify" has been added to app_server.c

26.2 参数定义 (app_server.c L133)

{"noverify", HITLS_SERVER_OPT_NO_VERIFY, HITLS_APP_OPT_VALUETYPE_NO_VALUE,
&nbsp;"Don't verify client certificate"}

26.3 处理函数 (app_server.c L241-244)

static&nbsp;int&nbsp;HandleServerNoVerify(HITLS_ServerParams *params)
{
&nbsp; &nbsp; params->verifyClient =&nbsp;false; &nbsp; &nbsp; &nbsp; &nbsp;// ← 核心:关闭客户端证书验证
&nbsp; &nbsp;&nbsp;return&nbsp;HITLS_APP_SUCCESS;
}

26.4 参数→处理函数映射 (app_server.c L299-319)

// 类型定义 (app_server.c L161-165):
// &nbsp; typedef int (*ServerOptHandleFunc)(HITLS_ServerParams *);
// &nbsp; typedef struct { int optType; ServerOptHandleFunc func; } ServerOptHandleFuncMap;

static&nbsp;const&nbsp;ServerOptHandleFuncMap g_serverOptHandleFuncMap[] = {
&nbsp; &nbsp; {HITLS_SERVER_OPT_ACCEPT, HandleServerAccept},
&nbsp; &nbsp; {HITLS_SERVER_OPT_PORT, HandleServerPort},
&nbsp; &nbsp;&nbsp;// ... 共 18 个条目 ...
&nbsp; &nbsp; {HITLS_SERVER_OPT_NO_VERIFY, HandleServerNoVerify}, &nbsp;&nbsp;// ← L308
&nbsp; &nbsp;&nbsp;// ...
&nbsp; &nbsp; {HITLS_APP_OPT_HELP, HandleServerHelp},
};

26.5 配置传播链

app_server.c:243 &nbsp; &nbsp; params->verifyClient = false
&nbsp; &nbsp; ↓
app_server.c → app_tls_common.c &nbsp;ConfCertVerification(config, verifyPeer=false, ...)
&nbsp; &nbsp; ↓
app_tls_common.c:470-486
&nbsp; &nbsp; HITLS_CFG_SetVerifyNoneSupport(config, !verifyPeer); &nbsp; // !false → true (无验证模式开启)
&nbsp; &nbsp; HITLS_CFG_SetClientVerifySupport(config, verifyPeer); &nbsp;// false → isSupportClientVerify=false
&nbsp; &nbsp; // verifyPeer=false → L480-486 不执行,isSupportNoClientCert 保持默认值 true
&nbsp; &nbsp; ↓
send_server_key_exchange.c:295-296
&nbsp; &nbsp; // 第一段 (L295): isSupportClientVerify == false → 不发送 CertificateRequest ✓
&nbsp; &nbsp; // 第二段 (L307): kxAlg == ECDHE → 强制发送 CertificateRequest ✗

26.6 -noverify 有效范围

| 能控制的 | 不能控制的 | | — | — | | isSupportClientVerify = false | HITLS_KEY_EXCH_ECDHE 强制 CertificateRequest | | isSupportNoClientCert = true (默认) | kxAlg 的比较逻辑 | | 双向身份验证开关 (第一段 L291-302) | ECDHE 密钥派生的协议级依赖 (第二段 L305-310) |


二十七、错误码参考

| 十六进制 | 十进制 | 宏名称 | 含义 | | — | — | — | — | | 0x20c0029 | 34340905 | HITLS_CERT_ERR_ENCODE | Failed to encode the certificate | | 0x2040017 | 33816599 | HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE | Not receive the peer certificate | | | | ↑ 常量名中 “CERTIFIACATE” 系源码拼写错误(应为 CERTIFICATE) | | | 0x27 | 39 | (外层封装错误) | Failed to create config and connection | | 0x20c001f | 34340895 | HITLS_CERT_ERR_CREATE_SIGN | 签名创建失败(SM2 userid 未正确配置) | | 0x20a000e | 34209806 | HITLS_REC_INVLAID_RECORD | 无效记录(握手消息解析失败) | | 0x2040005 | 33816581 | HITLS_MSG_HANDLE_CIPHER_SUITE_ERR | 密码套件错误(不支持或不匹配) |

来源: openhitls_7287/include/tls/hitls_error.h L165 (0x2040017), L340 (0x20c0029)

27.1 错误码位结构

0x2 0c 0029
&nbsp; │ &nbsp;│ &nbsp;└── 模块内错误号 (29)
&nbsp; │ &nbsp;└───── 模块 ID (0c = HITLS_CERT 模块, 04 = HITLS_MSG 模块)
&nbsp; └──────── 错误级别 (2 = ERROR)

二十八、关键注意事项

28.1 协议与编译

| 注意事项 | 详情 | | — | — | | ECDHE 单向不可行 | 协议级限制,源码头注释 (L303-304) 明确指出”Cause ECDHE relies on the client’s encrypt certificate”。不是 Bug,是 GM/T 0024 规范要求。适用于 ECDHE_SM4_CBC_SM3 和 ECDHE_SM4_GCM_SM3 两个密码套件 | | ECC 单向可行 | ECC 密钥交换模式下 kxAlg ≠ ECDHE,跳过 L307 判断,-noverify 可完全禁用客户端证书验证。适用于 ECC_SM4_CBC_SM3 和 ECC_SM4_GCM_SM3 两个密码套件 | | GCM 与 CBC 行为一致 | GCM 仅改变 AEAD 加密模式,不改变密钥交换算法。所有 ECDHE/ECC 的分析结论对 GCM 变体同样有效 | | IBC 不支持 | openhitls-0.3 分支无 IBC 密码套件,需更高版本分支 | | 开源 openhitls-0.3 分支 | 必须用分支 openhitls-0.3,HEAD=4c147a49 | | CMake 4.3.4 | 本环境预装版本,向下兼容 | | Python 3.13.14 | configure.py 从 Python 3.6+ 即可 | | -add_options 必须性 | --enable all 仅启用非国密模块,国密 7 个宏必须 --add_options 传递 |

28.2 证书与路径

| 注意事项 | 详情 | | — | — | | 证书路径正确性 | .crt 为文本转储+PEM 混合格式,hitls PEM 解析器可识别。.der 为纯 DER,由 cert callback 使用。自定义证书(custom_certs/)为纯 PEM 格式,无需中间 CA 证书链 | | LD_LIBRARY_PATH | 每个新终端必须设置为 export LD_LIBRARY_PATH=/home/kali/M/openhitls_7287/build:$LD_LIBRARY_PATH,注意末尾追加 :$LD_LIBRARY_PATH 以保留系统默认库路径 | | SM2 私钥格式 | hitls 的 genpkey 子命令输出纯 PKCS #8 格式(-----BEGIN PRIVATE KEY-----),无需额外过滤。源码自带的 .key 文件虽含 EC PARAMETERS 前缀,但 hitls 内置 PEM 解析器(hitls_bsl/pem.c)可自动跳过 | | 双证书目录选择 | sm2_with_userid/ 为含 userid 的 SM2 证书,sm2_cert/ 为纯 PKCS #8 私钥格式证书。两者均可用于 TLCP/DTLCP 测试,但命令行参数略有不同(sm2_cert 需先合并 root+intCa 为 chain.pem,且无 -chainCAfile 参数)。本操作记录全部测试优先使用自定义证书(/home/kali/M/custom_certs/),握手失败时回退到源码内置 sm2_with_userid 证书 |

28.3 执行流程

  • • 服务端必须先启动并显示 “Listening on …” 后再启动客户端
  • • tcpdump 必须先启动再启动客户端
  • • 客户端通过 echo "testdata" | hitls s_client 或 <<< "testdata" here-string 管道发送数据避免交互等待
  • • 测试完成后按顺序终止:客户端自动退出 → 服务端 sudo pkill -f "hitls s_server" → tcpdump Ctrl+C
  • • 服务端和客户端命令需要在不同终端中运行,不能在同一终端
  • • 实际复现:推荐使用脚本同步启动服务端和 tcpdump,然后单独运行客户端,确保抓包完整(参考 run_all_tests.sh 自动化脚本中的 run_test 函数)

28.4 端口复用警告

如果端口未正常释放(pkill 后立刻重启),可能看到 Address already in use,等待 60 秒或换端口。

二十九、使用建议

29.1 抓包分析

# 使用Wireshark分析pcap文件
wireshark captures/tlcp_ecdhe_two_way.pcap

# 使用tshark提取握手消息
tshark -r captures/tlcp_ecdhe_two_way.pcap -Y&nbsp;"tcp.port==4433"&nbsp;-V

# 提取应用层数据
tshark -r captures/tlcp_ecc_one_way.pcap -Y&nbsp;"tcp.port==4433"&nbsp;-T fields -e data

29.2 脚本复用

自动化测试脚本可保存用于后续测试:

# 备份脚本
cp&nbsp;run_all_tests.sh run_all_tests_backup.sh

# 修改测试数据
sed -i&nbsp;'s/利刃信安/测试数据123/g'&nbsp;run_all_tests.sh

# 仅测试特定密码套件
# 修改TEST_CASES数组,删除不需要的测试项

29.3 证书更新

证书有效期为365天,到期后需重新生成:

# 检查证书有效期
/home/kali/M/openhitls_7287/build/hitls x509 -in&nbsp;custom_certs/server_sign.crt \
&nbsp; &nbsp; -text -noout | grep&nbsp;"Not After"

# 重新生成证书(延长有效期至10年)
/home/kali/M/openhitls_7287/build/hitls x509 -req -in&nbsp;server_sign.csr \
&nbsp; &nbsp; -CA ca.crt -CAkey ca.key -days 3650 \
&nbsp; &nbsp; -userid&nbsp;"1234567812345678"&nbsp;-md sm3 \
&nbsp; &nbsp; -extfile openssl_ext.cnf -extensions server_sign \
&nbsp; &nbsp; -out server_sign.crt

三十、自动化测试

重要优化: 根据实际复现经验,创建自动化测试脚本可大幅提高测试效率。以下脚本可一次性完成16个测试用例(自定义证书)。实际交付时还创建了32用例版本( run_all_tests.sh),同时覆盖自定义证书和源码内置证书(sm2_with_userid),详见工作区 /home/kali/M/run_all_tests.sh

30.1 创建自动化测试脚本

cat&nbsp;> /home/kali/M/run_tests.sh <<&nbsp;'EOF'
#!/bin/bash
# openHiTLS TLCP/DTLCP 自动化测试脚本
# 测试4个密码套件 × 2个协议 × 2个认证模式 = 16个测试用例
# 注意: set -e 会使脚本在任一命令失败时退出,但 ECDHE 单向测试是预期失败的。
# 因此在客户端命令后使用 `|| true` 确保脚本不会因预期失败而终止。
set&nbsp;-e

# 配置变量
HITLS_BUILD="/home/kali/M/openhitls_7287/build"
CUSTOM_CERT="/home/kali/M/custom_certs"
CAPTURES_DIR="/home/kali/M/captures"
TEST_DATA="利刃信安"

export&nbsp;LD_LIBRARY_PATH=$HITLS_BUILD:$LD_LIBRARY_PATH

# 测试用例定义(完整16个,自定义证书)
declare&nbsp;-A TEST_CASES=(
&nbsp; &nbsp;&nbsp;# TLCP CBC tests
&nbsp; &nbsp; ["tlcp_ecdhe_cbc_two_way"]="TLCP|ECDHE_CBC|双向|4433|custom_tlcp_ecdhe_cbc_two_way.pcap"
&nbsp; &nbsp; ["tlcp_ecdhe_cbc_one_way"]="TLCP|ECDHE_CBC|单向|4433|custom_tlcp_ecdhe_cbc_one_way.pcap"
&nbsp; &nbsp; ["tlcp_ecc_cbc_two_way"]="TLCP|ECC_CBC|双向|4433|custom_tlcp_ecc_cbc_two_way.pcap"
&nbsp; &nbsp; ["tlcp_ecc_cbc_one_way"]="TLCP|ECC_CBC|单向|4433|custom_tlcp_ecc_cbc_one_way.pcap"
&nbsp; &nbsp;&nbsp;# DTLCP CBC tests
&nbsp; &nbsp; ["dtlcp_ecdhe_cbc_two_way"]="DTLCP|ECDHE_CBC|双向|4444|custom_dtlcp_ecdhe_cbc_two_way.pcap"
&nbsp; &nbsp; ["dtlcp_ecdhe_cbc_one_way"]="DTLCP|ECDHE_CBC|单向|4444|custom_dtlcp_ecdhe_cbc_one_way.pcap"
&nbsp; &nbsp; ["dtlcp_ecc_cbc_two_way"]="DTLCP|ECC_CBC|双向|4445|custom_dtlcp_ecc_cbc_two_way.pcap"
&nbsp; &nbsp; ["dtlcp_ecc_cbc_one_way"]="DTLCP|ECC_CBC|单向|4445|custom_dtlcp_ecc_cbc_one_way.pcap"
&nbsp; &nbsp;&nbsp;# TLCP GCM tests
&nbsp; &nbsp; ["tlcp_ecdhe_gcm_two_way"]="TLCP|ECDHE_GCM|双向|4433|custom_tlcp_ecdhe_gcm_two_way.pcap"
&nbsp; &nbsp; ["tlcp_ecdhe_gcm_one_way"]="TLCP|ECDHE_GCM|单向|4433|custom_tlcp_ecdhe_gcm_one_way.pcap"
&nbsp; &nbsp; ["tlcp_ecc_gcm_two_way"]="TLCP|ECC_GCM|双向|4433|custom_tlcp_ecc_gcm_two_way.pcap"
&nbsp; &nbsp; ["tlcp_ecc_gcm_one_way"]="TLCP|ECC_GCM|单向|4433|custom_tlcp_ecc_gcm_one_way.pcap"
&nbsp; &nbsp;&nbsp;# DTLCP GCM tests
&nbsp; &nbsp; ["dtlcp_ecdhe_gcm_two_way"]="DTLCP|ECDHE_GCM|双向|4444|custom_dtlcp_ecdhe_gcm_two_way.pcap"
&nbsp; &nbsp; ["dtlcp_ecdhe_gcm_one_way"]="DTLCP|ECDHE_GCM|单向|4444|custom_dtlcp_ecdhe_gcm_one_way.pcap"
&nbsp; &nbsp; ["dtlcp_ecc_gcm_two_way"]="DTLCP|ECC_GCM|双向|4445|custom_dtlcp_ecc_gcm_two_way.pcap"
&nbsp; &nbsp; ["dtlcp_ecc_gcm_one_way"]="DTLCP|ECC_GCM|单向|4445|custom_dtlcp_ecc_gcm_one_way.pcap"
)

# 运行单个测试
run_test() {
&nbsp; &nbsp;&nbsp;local&nbsp;test_name=$1
&nbsp; &nbsp;&nbsp;# 解析测试参数
&nbsp; &nbsp; IFS='|'&nbsp;read&nbsp;-r protocol suite_type auth_mode port pcap_file <<<&nbsp;"${TEST_CASES[$test_name]}"

&nbsp; &nbsp;&nbsp;echo&nbsp;"测试:&nbsp;$test_name&nbsp;($protocol&nbsp;+&nbsp;$suite_type&nbsp;+&nbsp;$auth_mode)"

&nbsp; &nbsp;&nbsp;# 构建密码套件名称
&nbsp; &nbsp;&nbsp;local&nbsp;cipher_suite=""
&nbsp; &nbsp;&nbsp;case&nbsp;$suite_type&nbsp;in
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ECDHE_CBC") cipher_suite="TLS_ECDHE_SM4_CBC_SM3"&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ECC_CBC") cipher_suite="TLS_ECC_SM4_CBC_SM3"&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ECDHE_GCM") cipher_suite="TLS_ECDHE_SM4_GCM_SM3"&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"ECC_GCM") cipher_suite="TLS_ECC_SM4_GCM_SM3"&nbsp;;;
&nbsp; &nbsp;&nbsp;esac

&nbsp; &nbsp;&nbsp;# 协议参数
&nbsp; &nbsp;&nbsp;local&nbsp;protocol_opt=""
&nbsp; &nbsp; [&nbsp;"$protocol"&nbsp;=&nbsp;"DTLCP"&nbsp;] && protocol_opt="-dtlcp"&nbsp;|| protocol_opt="-tlcp"

&nbsp; &nbsp;&nbsp;# 构建服务端命令
&nbsp; &nbsp;&nbsp;local&nbsp;server_cmd="$HITLS_BUILD/hitls s_server&nbsp;$protocol_opt&nbsp;-accept 127.0.0.1:$port"
&nbsp; &nbsp; server_cmd+=" -cipher&nbsp;$cipher_suite&nbsp;-CAfile&nbsp;$CUSTOM_CERT/ca.crt"
&nbsp; &nbsp; server_cmd+=" -tlcp_sign_cert&nbsp;$CUSTOM_CERT/server_sign.crt"
&nbsp; &nbsp; server_cmd+=" -tlcp_sign_key&nbsp;$CUSTOM_CERT/server_sign.key"
&nbsp; &nbsp; server_cmd+=" -tlcp_enc_cert&nbsp;$CUSTOM_CERT/server_enc.crt"
&nbsp; &nbsp; server_cmd+=" -tlcp_enc_key&nbsp;$CUSTOM_CERT/server_enc.key"
&nbsp; &nbsp; server_cmd+=" -provider default -state"
&nbsp; &nbsp; [&nbsp;"$auth_mode"&nbsp;=&nbsp;"单向"&nbsp;] && server_cmd+=" -noverify"

&nbsp; &nbsp;&nbsp;# 构建客户端命令
&nbsp; &nbsp;&nbsp;local&nbsp;client_cmd="$HITLS_BUILD/hitls s_client&nbsp;$protocol_opt"
&nbsp; &nbsp; client_cmd+=" -host 127.0.0.1 -port&nbsp;$port&nbsp;-cipher&nbsp;$cipher_suite"
&nbsp; &nbsp; client_cmd+=" -CAfile&nbsp;$CUSTOM_CERT/ca.crt -provider default -state"

&nbsp; &nbsp;&nbsp;# 双向认证添加客户端证书
&nbsp; &nbsp;&nbsp;if&nbsp;[&nbsp;"$auth_mode"&nbsp;=&nbsp;"双向"&nbsp;];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp; client_cmd+=" -tlcp_sign_cert&nbsp;$CUSTOM_CERT/client_sign.crt"
&nbsp; &nbsp; &nbsp; &nbsp; client_cmd+=" -tlcp_sign_key&nbsp;$CUSTOM_CERT/client_sign.key"
&nbsp; &nbsp; &nbsp; &nbsp; client_cmd+=" -tlcp_enc_cert&nbsp;$CUSTOM_CERT/client_enc.crt"
&nbsp; &nbsp; &nbsp; &nbsp; client_cmd+=" -tlcp_enc_key&nbsp;$CUSTOM_CERT/client_enc.key"
&nbsp; &nbsp;&nbsp;fi

&nbsp; &nbsp;&nbsp;# 启动tcpdump抓包
&nbsp; &nbsp;&nbsp;sudo&nbsp;tcpdump -i lo -w&nbsp;$CAPTURES_DIR/$pcap_file&nbsp;port&nbsp;$port&nbsp;> /dev/null 2>&1 &
&nbsp; &nbsp;&nbsp;local&nbsp;tcpdump_pid=$!
&nbsp; &nbsp;&nbsp;sleep&nbsp;2

&nbsp; &nbsp;&nbsp;# 启动服务端
&nbsp; &nbsp;&nbsp;$server_cmd&nbsp;> /tmp/server_$test_name.log&nbsp;2>&1 &
&nbsp; &nbsp;&nbsp;local&nbsp;server_pid=$!
&nbsp; &nbsp;&nbsp;sleep&nbsp;3

&nbsp; &nbsp;&nbsp;# 启动客户端并发送测试数据(交互模式)
&nbsp; &nbsp;&nbsp;echo&nbsp;"$TEST_DATA"&nbsp;|&nbsp;timeout&nbsp;10&nbsp;$client_cmd&nbsp;> /tmp/client_$test_name.log&nbsp;2>&1 ||&nbsp;true
&nbsp; &nbsp;&nbsp;sleep&nbsp;2

&nbsp; &nbsp;&nbsp;# 停止服务端和抓包
&nbsp; &nbsp;&nbsp;sudo&nbsp;kill&nbsp;$server_pid&nbsp;$tcpdump_pid&nbsp;2>/dev/null ||&nbsp;true
&nbsp; &nbsp;&nbsp;wait&nbsp;$server_pid&nbsp;$tcpdump_pid&nbsp;2>/dev/null ||&nbsp;true

&nbsp; &nbsp;&nbsp;# 显示结果
&nbsp; &nbsp;&nbsp;if&nbsp;[ -f&nbsp;$CAPTURES_DIR/$pcap_file&nbsp;];&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;local&nbsp;size=$(ls&nbsp;-lh&nbsp;$CAPTURES_DIR/$pcap_file&nbsp;| awk&nbsp;'{print $5}')
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;# 检查握手失败错误码
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;grep -q&nbsp;"0x20c0029\|0x2040017"&nbsp;/tmp/client_$test_name.log&nbsp;2>/dev/null;&nbsp;then
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;local&nbsp;err_code=$(grep -o&nbsp;"0x20c0029\|0x2040017"&nbsp;/tmp/client_$test_name.log&nbsp;|&nbsp;head&nbsp;-1)
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo&nbsp;"✗ 失败: 错误码$err_code&nbsp;(符合预期,ECDHE单向不支持)"
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;else
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo&nbsp;"✓ 成功: 握手完成"
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;fi
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo&nbsp;" &nbsp;pcap文件:&nbsp;$pcap_file&nbsp;($size)"
&nbsp; &nbsp;&nbsp;else
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;echo&nbsp;"✗ 失败: 未生成pcap文件"
&nbsp; &nbsp;&nbsp;fi

&nbsp; &nbsp;&nbsp;sleep&nbsp;5 &nbsp;# 等待端口释放
}

# 执行所有测试(按顺序)
echo&nbsp;"======================================"
echo&nbsp;"开始执行16个TLCP/DTLCP测试用例"
echo&nbsp;"======================================"
echo&nbsp;""
for&nbsp;test&nbsp;in&nbsp;"${!TEST_CASES[@]}";&nbsp;do
&nbsp; &nbsp;&nbsp;case&nbsp;$test&nbsp;in
&nbsp; &nbsp; &nbsp; &nbsp; tlcp_ecdhe_cbc_two_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; tlcp_ecdhe_cbc_one_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; tlcp_ecc_cbc_two_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; tlcp_ecc_cbc_one_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; dtlcp_ecdhe_cbc_two_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; dtlcp_ecdhe_cbc_one_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; dtlcp_ecc_cbc_two_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; dtlcp_ecc_cbc_one_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; tlcp_ecdhe_gcm_two_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; tlcp_ecdhe_gcm_one_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; tlcp_ecc_gcm_two_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; tlcp_ecc_gcm_one_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; dtlcp_ecdhe_gcm_two_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; dtlcp_ecdhe_gcm_one_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; dtlcp_ecc_gcm_two_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp; &nbsp; &nbsp; dtlcp_ecc_gcm_one_way) run_test&nbsp;$test&nbsp;;;
&nbsp; &nbsp;&nbsp;esac
done

echo&nbsp;"所有测试已完成!"
echo&nbsp;"======================================"
echo&nbsp;"生成16个pcap文件:"
ls&nbsp;-lh&nbsp;$CAPTURES_DIR/*.pcap
EOF

chmod&nbsp;+x /home/kali/M/run_tests.sh

30.2 执行自动化测试

cd&nbsp;/home/kali/M
sudo&nbsp;./run_tests.sh

实录输出:

======================================
开始执行16个TLCP/DTLCP测试用例
======================================

测试: tlcp_ecdhe_cbc_two_way (TLCP + ECDHE_CBC + 双向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_tlcp_ecdhe_cbc_two_way.pcap (4.0K)

测试: tlcp_ecdhe_cbc_one_way (TLCP + ECDHE_CBC + 单向)
✗ 失败: 错误码0x20c0029 (符合预期,ECDHE单向不支持)
&nbsp; pcap文件: custom_tlcp_ecdhe_cbc_one_way.pcap (2.3K)

测试: tlcp_ecc_cbc_two_way (TLCP + ECC_CBC + 双向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_tlcp_ecc_cbc_two_way.pcap (4.0K)

测试: tlcp_ecc_cbc_one_way (TLCP + ECC_CBC + 单向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_tlcp_ecc_cbc_one_way.pcap (3.0K)

测试: dtlcp_ecdhe_cbc_two_way (DTLCP + ECDHE_CBC + 双向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_dtlcp_ecdhe_cbc_two_way.pcap (3.5K)

测试: dtlcp_ecdhe_cbc_one_way (DTLCP + ECDHE_CBC + 单向)
✗ 失败: 错误码0x20c0029 (符合预期,ECDHE单向不支持)
&nbsp; pcap文件: custom_dtlcp_ecdhe_cbc_one_way.pcap (1.8K)

测试: dtlcp_ecc_cbc_two_way (DTLCP + ECC_CBC + 双向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_dtlcp_ecc_cbc_two_way.pcap (3.5K)

测试: dtlcp_ecc_cbc_one_way (DTLCP + ECC_CBC + 单向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_dtlcp_ecc_cbc_one_way.pcap (2.5K)

测试: tlcp_ecdhe_gcm_two_way (TLCP + ECDHE_GCM + 双向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_tlcp_ecdhe_gcm_two_way.pcap (3.7K)

测试: tlcp_ecdhe_gcm_one_way (TLCP + ECDHE_GCM + 单向)
✗ 失败: 错误码0x20c0029 (符合预期,ECDHE单向不支持)
&nbsp; pcap文件: custom_tlcp_ecdhe_gcm_one_way.pcap (2.2K)

测试: tlcp_ecc_gcm_two_way (TLCP + ECC_GCM + 双向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_tlcp_ecc_gcm_two_way.pcap (3.7K)

测试: tlcp_ecc_gcm_one_way (TLCP + ECC_GCM + 单向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_tlcp_ecc_gcm_one_way.pcap (2.9K)

测试: dtlcp_ecdhe_gcm_two_way (DTLCP + ECDHE_GCM + 双向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_dtlcp_ecdhe_gcm_two_way.pcap (3.3K)

测试: dtlcp_ecdhe_gcm_one_way (DTLCP + ECDHE_GCM + 单向)
✗ 失败: 错误码0x20c0029 (符合预期,ECDHE单向不支持)
&nbsp; pcap文件: custom_dtlcp_ecdhe_gcm_one_way.pcap (1.8K)

测试: dtlcp_ecc_gcm_two_way (DTLCP + ECC_GCM + 双向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_dtlcp_ecc_gcm_two_way.pcap (3.3K)

测试: dtlcp_ecc_gcm_one_way (DTLCP + ECC_GCM + 单向)
✓ 成功: 握手完成
&nbsp; pcap文件: custom_dtlcp_ecc_gcm_one_way.pcap (2.3K)

======================================
所有测试已完成!
======================================

生成的16个pcap文件:
custom_tlcp_ecdhe_cbc_two_way.pcap (4.0K)
custom_tlcp_ecdhe_cbc_one_way.pcap (2.3K)
custom_tlcp_ecc_cbc_two_way.pcap (4.0K)
custom_tlcp_ecc_cbc_one_way.pcap (3.0K)
custom_dtlcp_ecdhe_cbc_two_way.pcap (3.5K)
custom_dtlcp_ecdhe_cbc_one_way.pcap (1.8K)
custom_dtlcp_ecc_cbc_two_way.pcap (3.5K)
custom_dtlcp_ecc_cbc_one_way.pcap (2.5K)
custom_tlcp_ecdhe_gcm_two_way.pcap (3.7K)
custom_tlcp_ecdhe_gcm_one_way.pcap (2.2K)
custom_tlcp_ecc_gcm_two_way.pcap (3.7K)
custom_tlcp_ecc_gcm_one_way.pcap (2.9K)
custom_dtlcp_ecdhe_gcm_two_way.pcap (3.3K)
custom_dtlcp_ecdhe_gcm_one_way.pcap (1.8K)
custom_dtlcp_ecc_gcm_two_way.pcap (3.3K)
custom_dtlcp_ecc_gcm_one_way.pcap (2.3K)

30.3 测试结果矩阵

| 协议 | 密码套件 | 认证模式 | 测试结果 | pcap大小 | 交互数据 | 备注 | | — | — | — | — | — | — | — | | TLCP | ECDHE_CBC | 双向 | ✅ 成功 | 4.0K | 利刃信安 | 完整握手 | | TLCP | ECDHE_CBC | 单向 | ❌ 失败 | 2.3K | 无 | 错误码0x20c0029(协议限制) | | TLCP | ECC_CBC | 双向 | ✅ 成功 | 4.0K | 利刃信安 | 完整握手 | | TLCP | ECC_CBC | 单向 | ✅ 成功 | 3.0K | 利刃信安 | 无CertificateRequest | | DTLCP | ECDHE_CBC | 双向 | ✅ 成功 | 3.5K | 利刃信安 | UDP握手 | | DTLCP | ECDHE_CBC | 单向 | ❌ 失败 | 1.8K | 无 | 错误码0x20c0029(协议限制) | | DTLCP | ECC_CBC | 双向 | ✅ 成功 | 3.5K | 利刃信安 | UDP握手 | | DTLCP | ECC_CBC | 单向 | ✅ 成功 | 2.5K | 利刃信安 | UDP握手 | | TLCP | ECDHE_GCM | 双向 | ✅ 成功 | 3.7K | 利刃信安 | AEAD加密 | | TLCP | ECDHE_GCM | 单向 | ❌ 失败 | 2.2K | 无 | 错误码0x20c0029(协议限制) | | TLCP | ECC_GCM | 双向 | ✅ 成功 | 3.7K | 利刃信安 | AEAD加密 | | TLCP | ECC_GCM | 单向 | ✅ 成功 | 2.9K | 利刃信安 | AEAD加密 | | DTLCP | ECDHE_GCM | 双向 | ✅ 成功 | 3.3K | 利刃信安 | UDP+AEAD | | DTLCP | ECDHE_GCM | 单向 | ❌ 失败 | 1.8K | 无 | 错误码0x20c0029(协议限制) | | DTLCP | ECC_GCM | 双向 | ✅ 成功 | 3.3K | 利刃信安 | UDP+AEAD | | DTLCP | ECC_GCM | 单向 | ✅ 成功 | 2.3K | 利刃信安 | UDP+AEAD |

30.4 错误码对照

| 端点 | 错误码 | 宏名称 | 含义 | 源码位置 | 出现场景 | | — | — | — | — | — | — | | 客户端 | 0x20c0029 | HITLS_CERT_ERR_ENCODE | 加密证书编码失败 | parse_server_key_exchange.c L494-498 | ECDHE单向握手 | | 服务端 | 0x2040017 | HITLS_MSG_HANDLE_NO_PEER_CERTIFIACATE | 未收到客户端证书 | recv_certificate.c L340-354 | ECDHE强制要求客户端证书但未收到 |

实际验证: 所有ECDHE单向测试均出现错误码0x20c0029,符合GM/T 0024协议设计约束。


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:利刃信安 利刃信安 利刃信安《openHiTLS实现TLCP+DTLCP单向身份鉴别+双向身份鉴别通信过程并抓包分析》

人人都要学大脑 | 第7期 网络安全文章

人人都要学大脑 | 第7期

文章总结: 本文为中国电信安全网关产品线发布的第7期科普推文,但核心正文内容以图片形式加载且在当前文本中缺失。由于无法获取实际图文细节,本文未能提供具体的技术结
评论:0   参与:  0