ECDH密钥协商

ECDH密钥协商算法基于椭圆曲线密码系统(ECC),使用较短的密钥长度可提供与RSA或DH算法同等的安全等级,密钥长度位160 ~ 256比特的椭圆曲线算法与密钥长度位1024 ~ 3072比特的非ECC算法安全强度相同。

常用有限域上的椭圆曲线

椭圆曲线由以下参数组成
T=(p,a,b,G,n,h)

  • p 有限域中的大素数,长度一般224比特、256比特、384比特
  • a 整数,椭圆方程系数
  • b整数,椭圆方程系数
  • G,椭圆曲线上某点,生成元
  • n,为一个素数,表示椭圆曲线的阶
  • h,余因数
    其中G包含Gx和Gy 2个参数,非压缩模式以04开始,压缩模式以03开始,实际以非压缩模式
    通过模数p和系数a,b构成椭圆曲线方程
    y^2=x^3+ax+b mod p
    TLS支持很多椭圆曲线,常用的有2个secp256r1和secp284r1

secp256r1
大素数p长度256比特(32字节)

p=FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF
a=FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC
b=5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B
生成源G(Gx,Gy)
Gx=6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296
Gy=4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5
椭圆曲线的阶n
n=FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551

secp384r1
大素数p长度384比特(48字节)

省略。。。
ECDH密钥协商步骤

其实和DH思想一样,只不过这是基于椭圆曲线离散对数上实现的。

  • ECDH共享参数
    Alice和Bob进行ECDH密钥协商之前双方要有共同的ECDH共享参数即必须选择相同的椭圆曲线方程、大素数p、生成源G,实际中这些椭圆曲线已经被相关组织标准,比如上边的secp256r1、secp384r1,通过这个双方就确定了这些共享参数

  • ECHD密钥协商
    1.Alice选择一个比椭圆曲线阶小的随机数dA作为私密参数,计算QA=dA G=(xA,yA)发送给Bob
    2.Bob选择一个比椭圆曲线阶小的随机数dB作为私密参数,计算QB=dB G=(xB,yB)发送给Alice
    3.Bob收到QA并计算得到共享密钥参数KB=dB QA=dB(dA G)
    4.Alice收到QB并计算得到共享密钥参数KA=dA QB=dA(dB G)
    根据椭圆曲线结合律dB(dA G) = dA(dB G) = (xQ,yQ),即获得共享密钥KA=KB,KA和KB是一个坐标点,所以共享密钥可以是xQ,yQ两部分也可以是xQ单一部分,若共享曲线是secp256r1,则xQ,yQ长度均256比特,如共享曲线是secp384r1,则xQ,yQ长度均384比特
    如下图

mbedtls椭圆曲线模块
  • ecp.c/ecp.h 椭圆曲线基本操作
  • ecp_curves.c 椭圆曲线定义
  • ecdh.c/ecdh.h 椭圆曲线密钥协商
  • ecdsa.c/ecdsa.h 椭圆曲线数据签名

mbedtls所支持的椭圆曲线可以通过config.h 中下面这些宏使能或者关闭,这些宏是ecp_curves.c中条件的编译

/*** \def MBEDTLS_ECP_DP_SECP192R1_ENABLED** MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve* module.  By default all supported curves are enabled.** Comment macros to disable the curve and functions for it*/
#define MBEDTLS_ECP_DP_SECP192R1_ENABLED
#define MBEDTLS_ECP_DP_SECP224R1_ENABLED
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED
#define MBEDTLS_ECP_DP_SECP384R1_ENABLED
#define MBEDTLS_ECP_DP_SECP521R1_ENABLED
#define MBEDTLS_ECP_DP_SECP192K1_ENABLED
#define MBEDTLS_ECP_DP_SECP224K1_ENABLED
#define MBEDTLS_ECP_DP_SECP256K1_ENABLED
#define MBEDTLS_ECP_DP_BP256R1_ENABLED
#define MBEDTLS_ECP_DP_BP384R1_ENABLED
#define MBEDTLS_ECP_DP_BP512R1_ENABLED
#define MBEDTLS_ECP_DP_CURVE25519_ENABLED
mbedtls ECHDH例子

先要打开这些宏,这个例子还是想DH协商那样通过共享内存来模拟网络交换共享参数。

#define MBEDTLS_AES_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_BIGNUM_C
#define MBEDTLS_ECP_C            开启椭圆曲线基础运算
#define MBEDTLS_ECDH_C           开启椭圆曲线密钥协商
#define MBEDTLS_ECP_DP_SECP256R1_ENABLED 选择secp256r1曲线参数
#define MBEDTLS_AES_ROM_TABLES
#include <stdio.h>
#include <string.h>
#include <stdint.h>#include "mbedtls/ecdh.h"
#include "mbedtls/entropy.h"
#include "mbedtls/ctr_drbg.h"
#include "mbedtls/platform.h"#define assert_exit(cond, ret) \do { if (!(cond)) { \printf("  !. assert: failed [line: %d, error: -0x%04X]\n", __LINE__, -ret); \goto cleanup; \} } while (0)
/*
static int entropy_source(void *data, uint8_t *output, size_t len, size_t *olen)
{uint32_t seed;seed = sys_rand32_get();if (len > sizeof(seed)) {len = sizeof(seed);}memcpy(output, &seed, len);*olen = len;return 0;
}*/static void dump_buf(char *info, uint8_t *buf, uint32_t len)
{mbedtls_printf("%s", info);for (int i = 0; i < len; i++) {mbedtls_printf("%s%02X%s", i % 16 == 0 ? "\n     ":" ", buf[i], i == len - 1 ? "\n":"");}
}int main(void)
{int ret = 0;size_t olen;char buf[65];mbedtls_ecp_group grp;mbedtls_mpi cli_secret, srv_secret;mbedtls_mpi cli_pri, srv_pri;mbedtls_ecp_point cli_pub, srv_pub;mbedtls_entropy_context entropy;mbedtls_ctr_drbg_context ctr_drbg;uint8_t *pers = "simple_ecdh";mbedtls_mpi_init(&cli_pri); //mbedtls_mpi_init(&srv_pri);mbedtls_mpi_init(&cli_secret); mbedtls_mpi_init(&srv_secret);mbedtls_ecp_group_init(&grp); //初始化椭圆曲线群结构体mbedtls_ecp_point_init(&cli_pub); //初始化椭圆曲线点结构体 climbedtls_ecp_point_init(&srv_pub);//初始化椭圆曲线点结构体 srvmbedtls_entropy_init(&entropy); //初始化熵结构体mbedtls_ctr_drbg_init(&ctr_drbg);//初始化随机数结构体
/*mbedtls_entropy_add_source(&entropy, entropy_source, NULL,MBEDTLS_ENTROPY_MAX_GATHER, MBEDTLS_ENTROPY_SOURCE_STRONG);*/mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, (const uint8_t *) pers, strlen(pers));mbedtls_printf("\n  . setup rng ... ok\n");//加载椭圆曲线,选择SECP256R1ret = mbedtls_ecp_group_load(&grp, MBEDTLS_ECP_DP_SECP256R1);mbedtls_printf("\n  . select ecp group SECP256R1 ... ok\n");//cli生成公开参数ret = mbedtls_ecdh_gen_public(&grp,    //椭圆曲线结构体&cli_pri,//输出cli私密参数d&cli_pub,//输出cli公开参数Qmbedtls_ctr_drbg_random, &ctr_drbg);assert_exit(ret == 0, ret);mbedtls_ecp_point_write_binary(&grp, &cli_pub, //把cli的公开参数到处到buf中MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, sizeof(buf));dump_buf("  1. ecdh client generate public parameter:", buf, olen);//srv生成公开参数ret = mbedtls_ecdh_gen_public(&grp,    //椭圆曲线结构体&srv_pri,//输出srv私密参数d&srv_pub,//输出srv公开参数Qmbedtls_ctr_drbg_random, &ctr_drbg);assert_exit(ret == 0, ret);mbedtls_ecp_point_write_binary(&grp, &srv_pub, //把srv的公开参数导出到buf中MBEDTLS_ECP_PF_UNCOMPRESSED, &olen, buf, sizeof(buf));dump_buf("  2. ecdh server generate public parameter:", buf, olen);//cli计算共享密钥ret = mbedtls_ecdh_compute_shared(&grp,    //椭圆曲线结构体&cli_secret, //cli计算出的共享密钥&srv_pub, //输入srv公开参数Q&cli_pri, //输入cli本身的私密参数dmbedtls_ctr_drbg_random, &ctr_drbg);assert_exit(ret == 0, ret);//把cli计算出的共享密钥导出buf中mbedtls_mpi_write_binary(&cli_secret, buf, mbedtls_mpi_size(&cli_secret));dump_buf("  3. ecdh client generate secret:", buf, mbedtls_mpi_size(&cli_secret));//srv计算共享密钥ret = mbedtls_ecdh_compute_shared(&grp,   //椭圆曲线结构体&srv_secret, //srv计算出的共享密钥&cli_pub, //输入cli公开参数Q&srv_pri, //输入srv本身的私密参数dmbedtls_ctr_drbg_random, &ctr_drbg);assert_exit(ret == 0, ret);//把srv计算出的共享密钥导出buf中mbedtls_mpi_write_binary(&srv_secret, buf, mbedtls_mpi_size(&srv_secret));dump_buf("  4. ecdh server generate secret:", buf, mbedtls_mpi_size(&srv_secret));//比较2个大数是否相等ret = mbedtls_mpi_cmp_mpi(&cli_secret, &srv_secret);assert_exit(ret == 0, ret);mbedtls_printf("  5. ecdh checking secrets ... ok\n");cleanup:mbedtls_mpi_free(&cli_pri); mbedtls_mpi_free(&srv_pri);mbedtls_mpi_free(&cli_secret); mbedtls_mpi_free(&srv_secret);mbedtls_ecp_group_free(&grp);mbedtls_ecp_point_free(&cli_pub); mbedtls_ecp_point_free(&srv_pub);mbedtls_entropy_free(&entropy); mbedtls_ctr_drbg_free(&ctr_drbg);return 0;
}

运行结果

  . setup rng ... ok. select ecp group SECP256R1 ... ok1. ecdh client generate public parameter:04 D8 CC C3 43 FF 96 03 2A AB DD 1D 42 D3 D2 6EED 31 08 EB 6D 6E D3 1E F0 E8 5A 8B 8E E3 2B D602 B9 B3 AA 8F CF 99 EA 6E F5 3A 0B 04 34 4F 006D B4 28 29 0E DF 1B 2B 38 E7 34 A7 E5 AD B4 6B1D2. ecdh server generate public parameter:04 5C C6 24 F1 61 E5 B2 B8 F1 45 73 3E 99 F8 1BDB 95 13 5E 9D 59 BA DA 7F 78 01 AC C8 3C FD 7E2F 27 04 18 B0 29 7F 9E C0 BF 86 78 CF 49 1C 980B 03 75 B0 43 D0 36 F7 90 CF 54 49 8C F6 97 6DAF3. ecdh client generate secret:04 92 C4 4B 51 39 17 18 FB 6C 92 15 16 10 E6 D6B5 E4 CF 45 97 36 6C 12 22 E7 6E 83 02 C7 11 D94. ecdh server generate secret:04 92 C4 4B 51 39 17 18 FB 6C 92 15 16 10 E6 D6B5 E4 CF 45 97 36 6C 12 22 E7 6E 83 02 C7 11 D95. ecdh checking secrets ... ok

从运行结果看出

  • 模拟服务器和客户端均产生了不同的椭圆曲线公钥
  • 服务器和客户端公钥均采用非压缩模式,因为均以04开头
  • 双方采用secp256r1,所以生成公钥长度都为65字节,包括1字节压缩提示,32字节x坐标,32字节y坐标
  • 最终双方获得相同的共享密钥,共享密钥仅包括x坐标,所以长度是32字节

mbedtls学习(8)ECDH密钥协商相关推荐

  1. java使用ecdh密钥协商

    项目中刚好用到了ecdh进行密钥协商. java系列的文章比较少.记录下 首先密钥协商的大致过程: 双方A,B都使用EC算法(椭圆曲线算法)生成对应的公私钥.即A_PUB,A_PRI,B_PUB,B_ ...

  2. java ecdh秘钥交换,ECDH密钥协商算法

    ECDH是EC是"elliptic curves"的意思,DH是"Diffie-Hellman"的意思.它实际上是密钥协商算法,而不是加解密算法. 该算法可以用 ...

  3. HTTPS 和 SSL/TLS 协议:密钥交换(密钥协商)算法及其原理

    转自:https://blog.csdn.net/andylau00j/article/details/54583769 本系列的前一篇,咱们聊了"密钥交换的难点"以及" ...

  4. 扫盲 HTTPS 和 SSL/TLS 协议[3]:密钥交换(密钥协商)算法及其原理

    文章目录 ★密钥交换/协商机制要达到啥目的? ★密钥交换/协商机制的几种类型 ★基于 RSA 的密钥协商 ★基于 DH 的密钥协商 ★DH 的变种 ★基于 PSK 的密钥协商 ★基于 SRP 的密钥协 ...

  5. OpenSSL密码库算法笔记——第6.5.2章 密钥协商函数

    现在来看看OpenSSL中哪些函数是用来具体实现密钥协商的. ─────────────────────────────────────── int ECDH_compute_key(void *ou ...

  6. 公钥密码--Diffie-Hellman密钥协商算法

    公钥密码--Diffie-Hellman密钥协商算法 算法过程 正确性 安全性 博主是初学公钥密码,本意是想整理一些经典的密码系统,加深记忆也方便日后查找:整理成一个系列公钥密码,方便检索. 如果有错 ...

  7. 密钥协商(密钥交换)机制的讲解

    国标文件涉及密钥协商算法的函数 生成密钥协商参数并输出 计算会话密钥 产生协商数据并且计算会话密钥 密钥协商(交换)算法及其原理 密钥交换/协商目的 "密钥协商机制"是:(在身份认 ...

  8. 密钥协商算法的演变 —— RSA算法 - DH算法 - DHE算法 - ECDHE算法

    文章目录 1. RSA算法 RSA握手过程 RSA秘钥协商算法最大的缺陷 2. DH算法 3. DHE算法 4. ECDHE算法 ECDHE秘钥协商算法的TSL握手: 1. RSA算法 传统的 TLS ...

  9. 图表——SM2密钥协商与ECMQV对比

    1. SM2密钥协商流程图 2. SM2密钥协商与ECMQV对比 1995年,Menezes等人给出MQV方案,该方案与SM2方案仅在少量几个地方有差异: 紫色高亮的部分为SM2方案特有. 青色高亮的 ...

最新文章

  1. uber_这就是我本可以免费骑Uber的方式
  2. python3 处理 html转义字符
  3. Made in China 另解!
  4. 使用Mutex實現單一程式執行個體的注意事項(转)
  5. C语言计算分段函数pta,PTA浙大版《C语言程序设计(第3版)》题目集 练习2-11 计算分段函数[2] (10分)...
  6. 软件测试项目时间一般多少钱,项目的时间进度该如何估算?
  7. Windows进程通信之共享内存通信(C++)
  8. Kernel Samepage Merging | 同页合并
  9. 用户修改了信息jwt服务器怎么识别,django使用JWT保存用户登录信息
  10. spring in action 4 第6章 视图分发
  11. 咪咕:笔试题(20190916)
  12. PPP开源软件GMAP测试记录及原始数据比较
  13. 肝了一夜,用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换...
  14. 关于 Unbalanced calls to begin/end appearance transitions
  15. FPGA数码管显示自动计数+按键计数+蜂鸣器
  16. 嵌入式系统的概念,嵌入式系统的组成及特点,嵌入式系统的基本开发流程
  17. Elasticsearch:在搜索引擎中如何实现完全匹配(内容精确匹配)查询
  18. u大侠pe系统桌面计算机,如何使用U大侠PE系统修复引导文件
  19. angular.json
  20. 机器学习()PR曲线绘制

热门文章

  1. 海康威视IPC开启ONVIF
  2. 4.1-2黄金走势分析,一旦失守关键支撑,黄金白银恐将大跌
  3. 输在起跑线前——与日本孩子共进午餐有感--五色土网站 致中和
  4. dovecot mysql.conf_dovecot+mysql 收件服务、空壳邮件
  5. Nature旗下SCI期刊征收AI方向论文, 56%录用率, 5个月出录用
  6. 私域直播的好处是什么
  7. pubsub.js publish参数
  8. 云服务器怎样搭建静态网站?
  9. facenet在亚洲人脸上的效果测试
  10. StarGAN——生成你的明星脸