mbedTLS ECDH 密钥交换示例
源码位置: samples/security/mbedtls/ecdh 查看源码
功能说明
演示如何使用 mbedTLS 库进行 ECDH(椭圆曲线 Diffie-Hellman)密钥交换。本示例展示了 ECDH 的完整流程,包括客户端和服务器端密钥对生成、公钥交换、共享密钥计算和验证。
ECDH 是一种密钥交换协议,允许两个通信方在不安全的信道上建立共享密钥,而无需预先共享密钥。
硬件连接
无需外部连接,mbedTLS 为纯软件加密库。如果启用硬件加速(CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY=y),可以使用硬件加速功能。
示例内容
本示例循环测试所有支持的椭圆曲线(从 MBEDTLS_ECP_DP_SECP192R1 到 MBEDTLS_ECP_DP_CURVE448),对每条曲线执行以下步骤:
初始化随机数生成器(CTR_DRBG)和熵源
加载椭圆曲线组
客户端生成密钥对(私钥和公钥)
服务器端生成密钥对(私钥和公钥)
客户端使用服务器公钥和客户端私钥计算共享密钥
服务器端使用客户端公钥和服务器私钥计算共享密钥
验证客户端和服务器端计算的共享密钥是否相同
编译
重要提示:在编译前,请先确认您使用的开发板型号。SDK 目前支持以下开发板:
arcs_evb - ARCS EVB 评估板
arcs_mini - ARCS Mini 开发板
根据您的开发板型号,选择对应的编译命令:
在示例目录下执行编译:
# 使用 arcs_evb 开发板
./build.sh -C -DBOARD=arcs_evb
# 或使用 arcs_mini 开发板
./build.sh -C -DBOARD=arcs_mini
Note
如果在 SDK 根目录执行,需要指定示例路径:
# 使用 arcs_evb 开发板
./build.sh -C -S samples/<示例路径> -DBOARD=arcs_evb
# 或使用 arcs_mini 开发板
./build.sh -C -S samples/<示例路径> -DBOARD=arcs_mini
Note
确保已安装对应的工具链。
烧录
编译完成后,使用 SDK tools 目录下的 cskburn 工具烧录固件:
./tools/burn/cskburn -s /dev/ttyUSB0 -b 3000000 0x0 build/arcs.bin -C arcs
Note
烧录参数说明:
-s /dev/ttyUSB0:串口设备路径,需要根据实际情况修改 - Linux 系统:通常是/dev/ttyUSB0或/dev/ttyACM0- 可通过ls /dev/tty*命令查看可用串口设备 - 不同开发板或 USB 转串口芯片可能使用不同的设备名-b 3000000:烧录波特率(3Mbps)0x0:烧录起始地址build/arcs.bin:编译生成的固件路径-C arcs:芯片类型
注意事项:
确保开发板已正确连接到电脑
如果无法识别串口设备,请检查 USB 连接线是否正常,或尝试其他 USB 端口
预期输出
********Arcs SDK 0.1.0 @ v0.0.23.temp.docs-96-gf56c5084660d********
Running on hart-id: 1
I/elog [1034:42:44.159 1 elog_async] EasyLogger V2.2.99 is initialize success.
Hello, world!
mbedtls ecdh test
mbedtls ecdh test begin
=================0================
. setup rng ... ok
. select ecp group 0 ... ok
1. ecdh client generate public parameter:
04...
2. ecdh server generate public parameter:
04...
3. ecdh client generate secret:
...
4. ecdh server generate secret:
...
5. ecdh checking secrets ... ok
=================1================
...
mbedtls ecdh test end
说明:
输出开头包含系统启动信息和日志系统初始化信息
对每条椭圆曲线都会输出测试编号和测试结果
客户端和服务器端的公钥参数以十六进制格式输出
共享密钥以十六进制格式输出
最后验证两个共享密钥是否相同
核心 API
API |
说明 |
|---|---|
|
加载椭圆曲线组 |
|
生成 ECDH 密钥对(私钥和公钥) |
|
计算共享密钥 |
|
将椭圆曲线点写入二进制格式 |
|
将大整数写入二进制格式 |
|
比较两个大整数 |
|
初始化 CTR_DRBG 随机数生成器 |
|
初始化熵源 |
关键代码
/* 初始化随机数生成器 */
mbedtls_entropy_context entropy;
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_init(&entropy);
mbedtls_ctr_drbg_init(&ctr_drbg);
mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy,
(const uint8_t *) pers, strlen(pers));
/* 加载椭圆曲线组 */
mbedtls_ecp_group grp;
mbedtls_ecp_group_init(&grp);
mbedtls_ecp_group_load(&grp, grp_id);
/* 客户端生成密钥对 */
mbedtls_mpi cli_pri;
mbedtls_ecp_point cli_pub;
mbedtls_mpi_init(&cli_pri);
mbedtls_ecp_point_init(&cli_pub);
mbedtls_ecdh_gen_public(&grp, &cli_pri, &cli_pub,
mbedtls_ctr_drbg_random, &ctr_drbg);
/* 服务器端生成密钥对 */
mbedtls_mpi srv_pri;
mbedtls_ecp_point srv_pub;
mbedtls_mpi_init(&srv_pri);
mbedtls_ecp_point_init(&srv_pub);
mbedtls_ecdh_gen_public(&grp, &srv_pri, &srv_pub,
mbedtls_ctr_drbg_random, &ctr_drbg);
/* 客户端计算共享密钥 */
mbedtls_mpi cli_secret;
mbedtls_mpi_init(&cli_secret);
mbedtls_ecdh_compute_shared(&grp, &cli_secret, &srv_pub, &cli_pri,
mbedtls_ctr_drbg_random, &ctr_drbg);
/* 服务器端计算共享密钥 */
mbedtls_mpi srv_secret;
mbedtls_mpi_init(&srv_secret);
mbedtls_ecdh_compute_shared(&grp, &srv_secret, &cli_pub, &srv_pri,
mbedtls_ctr_drbg_random, &ctr_drbg);
/* 验证共享密钥是否相同 */
int ret = mbedtls_mpi_cmp_mpi(&cli_secret, &srv_secret);
if (ret == 0) {
mbedtls_printf(" 5. ecdh checking secrets ... ok\n");
}
椭圆曲线说明
本示例测试所有 mbedTLS 支持的椭圆曲线,包括:
SECP 曲线:SECP192R1, SECP224R1, SECP256R1, SECP384R1, SECP521R1
SECP Koblitz 曲线:SECP192K1, SECP224K1, SECP256K1
Brainpool 曲线:BP256R1, BP384R1, BP512R1
其他曲线:CURVE25519, CURVE448
配置说明
必需配置
CONFIG_SDK_MODULE_MBEDTLS=y: 启用 mbedTLS 模块CONFIG_MBEDTLS_ECP_C=y: 启用椭圆曲线支持CONFIG_MBEDTLS_ECDH_C=y: 启用 ECDH 支持CONFIG_MBEDTLS_ECP_ALL_ENABLED=y: 启用所有椭圆曲线CONFIG_MBEDTLS_HARDWARE_ENTROPY=y: 启用硬件熵源(可选)
硬件加速配置(可选)
CONFIG_MBEDTLS_ATCA_HW_ECDSA_VERIFY=y: 启用 ECC 硬件加速(用于 ECDSA 验证,可能对 ECDH 也有帮助)
注意事项
随机数生成器: ECDH 密钥生成需要高质量的随机数,必须正确初始化熵源和 CTR_DRBG
资源清理: 使用完所有 mbedTLS 结构后,必须调用相应的
free()函数释放资源椭圆曲线选择: 不同的椭圆曲线提供不同的安全级别和性能,应根据实际需求选择
公钥格式: 公钥以未压缩格式(
MBEDTLS_ECP_PF_UNCOMPRESSED)输出,包含完整的点坐标共享密钥: 计算出的共享密钥是原始的大整数,实际使用时可能需要进一步处理(如密钥派生)
测试范围: 本示例测试所有支持的椭圆曲线,某些曲线可能在某些平台上不支持或性能较差
错误处理: 代码使用
assert_exit宏进行错误处理,实际应用中应使用更完善的错误处理机制