mbedtls学习(7)DH密钥协商

DH密钥协商算法

RSA算法再一定程度熵解决了密钥配送问题,但也可以用DH密钥协商算法来解决密钥配送问题。DH密钥协商算法时基于离散对数问题。DH(Diffie-Hellman)密钥协商是由Whitfield Diffie和Martin Hellman提出,该算法允许通讯双方再不安全的信道交换数据,从而协商出一个会话密钥。

DH密钥协商原理
  • DH共享参数

Alice和Bob进行DH密钥协商之前双方要有共同的DH共享参数即大素数p和生成源a,为了保证DH协商的安全性,大素数p的长度不应小于2048bit(256字节),RFC7919 Negotiated Finite Field Diffie-Hellman Ephemeral Parameters for Transport Layer Security (TLS)中规定了5组DH共享参数可以直接用里面的。

  • DH密钥协商

1.Alice选择一个随机数x(1<=x<=p-1),算法得到公开参数A≡a^x mod p发送给Bob
2.Bob选择一个随机数y(1<=y<=p-1),算法得到公开参数B≡a^y mod p发送给Alice
3.Bob收到A并计算得到共享密钥参数k≡A^y mode p → (a^x)^y mod p → a^xy mod p
4.Alice收到B并计算得到共享密钥参数k≡B^y mode p → (a^y)^x mod p → a^xy mod p
5.最终的k就是用于对称加密的会话密钥,如下图
在这里插入图片描述

  • DH密钥协商的安全性

DH密钥协商不会对公开参数的发送者进行身份认证,因此无法阻止主动攻击者,如果攻击Mallory入侵了Alice和Bob的非安全通道,当Alice和Bob进行DH密钥协商时,攻击者Mallory对于Alice来说冒充Bob,对于Bob来说冒充Alice,这样就能对Alice和Bob之间发送的信息进行解密,身份认证的问题需要加入ECDSA或者RSA。
下面是在mbedtls\programs\pkey目录下
dh_client.c ,DH客户端
dh_server.c,DH服务器
dh_genprime.c,产生DH共享参数,保存在dh_prime.txt
rsa_genkey.c,产生RSA密钥对,保存在rsa_priv.txt、rsa_pub.txt
这几个文件表达的意思,这里DH协商用RSA来做身份认证。
在这里插入图片描述

DH协商例子

其实上面的dh_client.cdh_server.c就是DH协商的例子,这里通过内存共享的方式模拟网络通讯获得DH公钥,注意这里没有进行身份认证。要打开以下宏

#define MBEDTLS_AES_C
#define MBEDTLS_SHA256_C
#define MBEDTLS_ENTROPY_C
#define MBEDTLS_CTR_DRBG_C
#define MBEDTLS_MD_C
#define MBEDTLS_BIGNUM_C    开启大数计算
#define MBEDTLS_DHM_C       开启DH密钥协商模块
#define MBEDTLS_GENPRIME    开启大素数生成
#define MBEDTLS_AES_ROM_TABLES
#include <stdio.h>
#include <string.h>
#include <stdint.h>

#include "mbedtls/dhm.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)

#define GENERATOR   "2"   //生成元
//大素数
#define T_P          "FFFFFFFFFFFFFFFFADF85458A2BB4A9AAFDC5620273D3CF1D8B9C583CE2D3695" \
                     "A9E13641146433FBCC939DCE249B3EF97D2FE363630C75D8F681B202AEC4617A"\
                     "D3DF1ED5D5FD65612433F51F5F066ED0856365553DED1AF3B557135E7F57C935"\
                     "984F0C70E0E68B77E2A689DAF3EFE8721DF158A136ADE73530ACCA4F483A797A"\
                     "BC0AB182B324FB61D108A94BB2C8E3FBB96ADAB760D7F4681D4F42A3DE394DF4"\
                     "AE56EDE76372BB190B07A7C8EE0A6D709E02FCE1CDF7E2ECC03404CD28342F61"\
                     "9172FE9CE98583FF8E4F1232EEF28183C3FE3B1B4C6FAD733BB5FCBC2EC22005"\
                     "C58EF1837D1683B2C6F34A26C1B2EFFA886B423861285C97FFFFFFFFFFFFFFFF"
/*
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 n = 0;
    const char *pers = "simple_dh";
    uint8_t cli_pub[256], cli_secret[256];
    uint8_t srv_pub[256], srv_secret[256];
	
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    mbedtls_dhm_context dhm_cli, dhm_srv;

    mbedtls_dhm_init(&dhm_cli); //初始化dhm_cli结构体
    mbedtls_dhm_init(&dhm_srv); //初始化dhm_srv结构体
    mbedtls_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);*/
	//根据个性化字符串更新种子
    ret = mbedtls_ctr_drbg_seed(&ctr_drbg, mbedtls_entropy_func, &entropy, 
                                (const unsigned char *) pers, strlen(pers));
    assert_exit(ret == 0, ret);
    mbedtls_printf("\n  . setup rng ... ok\n\n");

    mbedtls_mpi_read_string(&dhm_srv.P, 16, T_P);//设置dh_srv共享参数之大素数
    mbedtls_mpi_read_string(&dhm_srv.G, 10, GENERATOR);//设置dh_srv共享参数之生成元
    dhm_srv.len = mbedtls_mpi_size(&dhm_srv.P);//大素数长度

    mbedtls_mpi_read_string(&dhm_cli.P, 16, T_P);//设置dh_cli共享参数之大素数
    mbedtls_mpi_read_string(&dhm_cli.G, 10, GENERATOR);//设置dh_cli共享参数之生成元
    dhm_cli.len = mbedtls_mpi_size(&dhm_cli.P);//大素数长度
    mbedtls_printf("  1. dh generate 2048 bit prime(G, P) ... ok\n");

	//生成dh_srv公开参数
    ret = mbedtls_dhm_make_public(&dhm_srv, 256, srv_pub, sizeof(srv_pub), 
                                            mbedtls_ctr_drbg_random, &ctr_drbg);
    assert_exit(ret == 0, ret);
    dump_buf("  2. dh server generate public parameter:", srv_pub, sizeof(srv_pub));

	//生成dh_cli公开参数
    ret = mbedtls_dhm_make_public(&dhm_cli, 256, cli_pub, sizeof(cli_pub), 
                                            mbedtls_ctr_drbg_random, &ctr_drbg);
    assert_exit(ret == 0, ret);
    dump_buf("  3. dh client generate public parameter:", cli_pub, sizeof(cli_pub));

	//这里模拟dh_srv获得dh_cli发来的公开参数
    ret = mbedtls_dhm_read_public(&dhm_srv, cli_pub, sizeof(cli_pub));
    assert_exit(ret == 0, ret);
    mbedtls_printf("  4. dh server read public ... ok\n"); 

	//这里模拟dh_cli获得dh_srv发来的公开参数
    ret = mbedtls_dhm_read_public(&dhm_cli, srv_pub, sizeof(srv_pub));
    assert_exit(ret == 0, ret);
    mbedtls_printf("  5. dh client read public ... ok\n");

	//dh_srv计算出共享密钥
    ret = mbedtls_dhm_calc_secret(&dhm_srv, srv_secret, sizeof(srv_secret), 
                                    &n, mbedtls_ctr_drbg_random, &ctr_drbg);
    assert_exit(ret == 0, ret);
    dump_buf("  6. dh server generate secret:", srv_secret, sizeof(srv_secret));

	//dh_cli计算出共享密钥
    ret = mbedtls_dhm_calc_secret(&dhm_cli, cli_secret, sizeof(cli_secret), 
                                    &n, mbedtls_ctr_drbg_random, &ctr_drbg);
    assert_exit(ret == 0, ret);
    dump_buf("  7. dh client generate secret:", cli_secret, sizeof(cli_secret));

	//这里判断dh_srv 、dh_cli各自计算得到这共享密钥知否一致
    ret = memcmp(cli_secret, srv_secret, sizeof(srv_secret));
    assert_exit(ret == 0, ret);
    mbedtls_printf("  8. dh checking secrets ... ok\n\n");

cleanup:
    mbedtls_dhm_free(&dhm_cli); //释放dh结构体
    mbedtls_dhm_free(&dhm_srv);
    mbedtls_entropy_free(&entropy); //释放熵结构体
    mbedtls_ctr_drbg_free(&ctr_drbg);//释放随机数结构体

    return ret;    
}

运行如下


  . setup rng ... ok

  1. dh generate 2048 bit prime(G, P) ... ok
  2. dh server generate public parameter:
     3A 32 A4 91 83 9D 1C 1C BD 8B 58 42 5C 9C F1 16
     AC E5 98 93 77 01 99 FA 07 5C 13 7F C7 FB AF 5D
     42 51 62 F0 93 C9 B5 73 D1 DC EC C2 2B 3C D2 6B
     B5 4E E1 CA B7 08 34 F7 43 B6 19 16 C3 94 12 72
     D4 55 C1 9D 08 BA 1A 75 EE 8C A5 09 E3 D4 35 1C
     52 04 7B 14 54 47 3A C6 C4 E6 11 9C BA 83 B3 95
     63 12 17 08 98 20 D5 FF 77 70 1C 31 62 0A 37 37
     04 EF 94 B8 3E FF 6B 21 D2 01 8D 71 EA 1E 98 A1
     40 F8 A9 23 72 49 39 AB CF D4 F8 68 EA 9D F8 77
     CE 81 AC E5 4B 65 E3 45 6F AD 26 B9 6D BA 09 B1
     0D BD 6E F9 C7 92 2A 6E EA 6B 02 58 2A 83 C2 11
     1E AD 73 87 12 3F 42 41 55 10 6E 57 A9 37 20 02
     3D 0B 7F DA B0 AB 2B 14 98 66 FF 48 D5 CE 96 31
     9D BB C0 4A 46 4C 6F 45 2A 93 68 94 40 8B F5 5B
     E5 F9 95 C0 24 00 CD E5 6C 90 ED 84 75 05 5C 26
     B8 7B 82 BB FD DC D2 41 AD 5E 7E C6 B4 A7 4D 0C
  3. dh client generate public parameter:
     C5 6E C2 B0 60 88 E2 28 69 AD C0 5B 9E 00 41 4E
     EA A4 D0 4F E2 CA EC 03 37 45 12 6B 1C 9C 86 31
     34 1C C3 83 4F 4B E4 C9 FC FE C6 C3 8B 8F ED B6
     EF A0 FD A0 28 3E F1 54 73 B0 9D 58 77 F4 33 FF
     55 A0 4D 32 98 47 06 F7 4E B1 C9 45 92 7B FC 25
     E7 CF B8 83 16 9A F0 E0 9B 77 20 6C 58 C3 8D 9B
     E9 4F AA D0 26 F6 B3 B6 CB B3 1F 46 50 F7 06 91
     7A 9E BC DD E7 5E 74 3B 09 A6 DD EA 0F BD 97 18
     1B EF 6B 82 7E 54 DC F5 C9 76 75 BA B4 51 E7 58
     96 94 03 A2 78 9D A0 E5 48 22 5E 79 A7 1D AC 48
     41 F8 EA 02 91 F1 3F 6A 85 A8 01 47 40 6F 6A C2
     80 42 CE E6 F3 B5 A5 84 00 8D AA 75 0B 85 92 9D
     0E C5 CA A0 AF 0E 9A 44 A1 E4 85 79 54 7D 1D FF
     53 64 AA 02 26 44 BF D3 44 9B 13 9F 7C 60 33 15
     6F 36 54 A2 25 EE D1 83 1E 18 0D 85 C0 77 6E FA
     73 C6 ED 1D 23 28 AD 48 C1 23 8E F6 BB C6 81 48
  4. dh server read public ... ok
  5. dh client read public ... ok
  6. dh server generate secret:
     3B F9 8F 25 5C 32 38 43 6A 3E 93 96 98 A5 55 5D
     9E 99 A4 DC B2 34 B8 81 D4 17 26 B4 AC 2A 5B F8
     7D AE A2 72 D4 7C CF F7 89 34 45 2C 9F DA 01 77
     54 AE B4 66 F3 5E 2B 2F 4C B1 93 69 3A 32 59 57
     A8 0F 84 8D FC 1C A2 1C D0 2B 40 36 2F 47 54 8A
     24 F2 23 D1 EC 7E 48 1E DB 83 6A A4 5B A8 05 05
     45 A6 2E 2A 6A 91 45 4C 2F 22 FD 87 E5 3C 55 A8
     A6 66 E6 1B FD 9A 56 15 25 39 6E 2A F1 FB E5 CB
     2E B0 83 57 7B C6 00 AC A5 4A 4D 5B C7 EC D6 DE
     1F C4 3B 6F C7 7A 4A B6 52 D1 52 2D FF 6E 77 8B
     DC 29 7B B5 E0 F3 46 23 83 58 8D 02 6D 7E 73 6D
     B8 FC E7 93 F8 83 21 29 3D E8 04 4E 07 60 EF B7
     A6 F0 BB 8A 41 1A 4E 9F A0 B5 A4 93 64 16 8F A5
     D3 7C B4 D5 4D 20 EC C4 91 2A 57 1D 3F 11 FC 5F
     61 5A AF CA 78 96 58 1E CE 00 0C 2A 05 56 14 F7
     4E 91 79 5B 62 5C 40 C4 A2 D0 9B 9C 84 F1 5F 96
  7. dh client generate secret:
     3B F9 8F 25 5C 32 38 43 6A 3E 93 96 98 A5 55 5D
     9E 99 A4 DC B2 34 B8 81 D4 17 26 B4 AC 2A 5B F8
     7D AE A2 72 D4 7C CF F7 89 34 45 2C 9F DA 01 77
     54 AE B4 66 F3 5E 2B 2F 4C B1 93 69 3A 32 59 57
     A8 0F 84 8D FC 1C A2 1C D0 2B 40 36 2F 47 54 8A
     24 F2 23 D1 EC 7E 48 1E DB 83 6A A4 5B A8 05 05
     45 A6 2E 2A 6A 91 45 4C 2F 22 FD 87 E5 3C 55 A8
     A6 66 E6 1B FD 9A 56 15 25 39 6E 2A F1 FB E5 CB
     2E B0 83 57 7B C6 00 AC A5 4A 4D 5B C7 EC D6 DE
     1F C4 3B 6F C7 7A 4A B6 52 D1 52 2D FF 6E 77 8B
     DC 29 7B B5 E0 F3 46 23 83 58 8D 02 6D 7E 73 6D
     B8 FC E7 93 F8 83 21 29 3D E8 04 4E 07 60 EF B7
     A6 F0 BB 8A 41 1A 4E 9F A0 B5 A4 93 64 16 8F A5
     D3 7C B4 D5 4D 20 EC C4 91 2A 57 1D 3F 11 FC 5F
     61 5A AF CA 78 96 58 1E CE 00 0C 2A 05 56 14 F7
     4E 91 79 5B 62 5C 40 C4 A2 D0 9B 9C 84 F1 5F 96
  8. dh checking secrets ... ok
  • 1
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
mbedtls dh是指使用mbedtls库中的DHM(Diffie-Hellman-Merkle)功能。DHM是一种密钥交换协议,用于在两个通信方之间安全地协商共享密钥。引用中的mbedtls_dhm_init函数用于初始化DHM上下文,而引用中的mbedtls_dhm_free函数则用于释放和清除DHM上下文的组件。 在使用mbedtls库时,可以根据需要编辑配置文件mbedtls_config_dhm.h来进行配置。引用中给出了一个针对本实验的配置文件示例。该配置文件定义了一些系统支持和mbed功能支持的选项,以及需要包含的mbed模块。可以根据具体需求取消或启用相应的选项来进行自定义配置。 总结来说,mbedtls dh是通过mbedtls库中的DHM功能实现的一种密钥交换协议,用于在通信方之间生成共享密钥。使用mbedtls库时,可以通过DHM上下文的初始化和释放函数来对DHM进行操作,并可以根据需要编辑配置文件来进行自定义配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [mbedtls | 07 - DH秘钥协商算法的配置与使用](https://blog.csdn.net/Mculover666/article/details/108856473)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值