一、openssl DH算法接口使用示例:

//gcc -g -lssl dh_test.c -lcrypto -L /usr/local/lib/
#include<openssl/dh.h>
#include<memory.h>void print_bigdata(const BIGNUM *b, char *title) {unsigned char a[2048] = {0};int len = BN_bn2bin(b, a);int i = 0, c = 0;printf("===================================== %s =====================================\n", title);for (; i<len; i++) {printf("0x%02x ", a[i]);c++;if (!(c%16))printf("\n");}printf("\n");
}void print_hexdata(unsigned char *b, int len, char *title) {int i = 0, c = 0;printf("===================================== %s =====================================\n", title);for (; i<len; i++) {printf("0x%02x ", b[i]);c++;if (!(c%16))printf("\n");}printf("\n");
}int main()
{int key_bits = 768;int ret;// 构造DH数据结构DH *d1 = NULL;d1=DH_new();// 生成d密钥参数,该密钥参数是可以公开的ret=DH_generate_parameters_ex(d1,key_bits,DH_GENERATOR_2,NULL);if(ret!=1){printf("DH_generate_parameters_ex err!\n");return -1;}ret=DH_generate_key(d1);if(ret!=1){printf("DH_generate_key err!\n");return -1;}// 获取d1的p,g,pub_key,pri_keyconst BIGNUM *d1p = NULL, *d1g = NULL;DH_get0_pqg(d1, &d1p, NULL, &d1g);const BIGNUM *d1pub_key = NULL, *d1priv_key = NULL;DH_get0_key(d1, &d1pub_key, &d1priv_key);print_bigdata(d1p,"d1p");print_bigdata(d1pub_key,"d1pub_key");print_bigdata(d1priv_key,"d1priv_key");// 构造DH数据结构DH *d2 = NULL;d2=DH_new();// p 和 g 为公开的密钥参数,因此可以拷贝,通过p,g参数可以构造d2BIGNUM *t_p = NULL, *t_g = NULL;t_p=BN_dup(d1p);t_g=BN_dup(d1g);DH_set0_pqg(d2, t_p, NULL, t_g);// 生成公私钥,用于测试生成共享密钥ret=DH_generate_key(d2);if(ret!=1){printf("DH_generate_key err!\n"); return -1; }// 获取d2的p,g,pub_key,pri_keyconst BIGNUM *d2p = NULL, *d2g = NULL;DH_get0_pqg(d2, &d2p, NULL, &d2g);const BIGNUM *d2pub_key = NULL, *d2priv_key = NULL;DH_get0_key(d2, &d2pub_key, &d2priv_key);print_bigdata(d2p,"d2p");print_bigdata(d2pub_key,"d2pub_key");print_bigdata(d2priv_key,"d2priv_key");// 计算共享密钥:d1+d2pub_key,d2+d1pub_key生成相同的共享密钥unsigned char sharekey1[1024] = {0};unsigned char sharekey2[1024] = {0};int len1=DH_compute_key(sharekey1,d2pub_key,d1);int len2=DH_compute_key(sharekey2,d1pub_key,d2);if(len1!=len2){printf("生成共享密钥失败\n");return -1;}if(memcmp(sharekey1,sharekey2,len1)!=0){printf("生成共享密钥失败\n");return -1;}print_hexdata(sharekey1, len1, "sharekey1");print_hexdata(sharekey2, len2, "sharekey2");DH_free(d1);DH_free(d2);return 0;
}

二、下一段代码展示了读取字符数组构造dh参数,并生成对应的dh对象,完成公钥生成和共享密钥生成,步骤如下:

1.先使用标准openssl接口生成一组密钥对,p,g,priv,pub值(协议数据);

2.d1生成pubkey:提取协议数据p,g,priv三组值,通过调用接口DH_set0_pqg(d1, t_p, NULL, t_g)和DH_set0_key(d1, NULL, pri1)来设置对应的参数,调用DH_generate_key来生成新的dh对象,并生成pubkey,通过对比生成的pubkey,确认正确生成;

3.d2对象生成:提取协议数据p,g参数,设置d2对象,并通过调用DH_generate_key来生成新的dh对象,保存新的p,g,pub,priv值,调用DH_compute_key,联合d1,d2来生成共享密钥,存储sharekey;

4.验证sharekey:使用p,g,pub,priv生成d2对象,因为d1,d2,就是第3步的dh对象参数,那么使用d1,d2生成的共享密钥一定与第3步存储的sharekey一致;

5.通过执行下述代码进行了验证:

//gcc -g -lssl dh_test.c -lcrypto -L /usr/local/lib/
#include<openssl/dh.h>
#include<memory.h>void print_bigdata(const BIGNUM *b, char *title) {unsigned char a[2048] = {0};int len = BN_bn2bin(b, a);int i = 0, c = 0;printf("===================================== %s =====================================\n", title);for (; i<len; i++) {printf("0x%02x ", a[i]);c++;if (!(c%16))printf("\n");}printf("\n");
}void print_hexdata(unsigned char *b, int len, char *title) {int i = 0, c = 0;printf("===================================== %s =====================================\n", title);for (; i<len; i++) {printf("0x%02x ", b[i]);c++;if (!(c%16))printf("\n");}printf("\n");
}static char dh_g_2[] = {0x02};static char dh_pa_768[] = {0xa5,0x2b,0xb2,0x89,0xd6,0xc9,0x1a,0x25,0x2f,0xca,0x89,0x52,0x51,0x2a,0x00,0x1e,0xd9,0x3d,0x92,0x50,0x58,0xa3,0x8e,0x23,0x7a,0x98,0x85,0xe1,0x5b,0x98,0x06,0x2f,0x7e,0xd2,0x21,0x01,0xa4,0x67,0xc9,0x5a,0x1a,0x12,0x9c,0x96,0x4a,0x08,0x75,0x8c,0xb9,0xb4,0x46,0xc1,0x62,0x76,0xbc,0xdb,0xe9,0xdd,0xbc,0x2d,0x5e,0x78,0x90,0xe7,0x52,0x50,0x27,0x3c,0xad,0x88,0x9c,0xc3,0xac,0x8b,0x91,0x52,0x7f,0x10,0x35,0xb2,0xb5,0x20,0x8f,0x6b,0x81,0xab,0xbe,0x07,0x1c,0x8e,0x42,0x9d,0x16,0x9e,0x65,0xdb
};static char dh_xa_768[] = {0x72,0xb2,0x3d,0x8b,0xa1,0x2a,0x89,0x72,0x56,0xd0,0x44,0xe6,0x60,0x3a,0x79,0x0d,0x70,0x85,0xa1,0xef,0xc1,0x99,0x7c,0xc8,0x4d,0x5d,0x16,0x46,0xae,0x7d,0xf8,0xa8,0x25,0x61,0xd1,0x4d,0x9a,0x9a,0x2d,0xe0,0x56,0x2f,0x9f,0x49,0x9a,0x07,0xf0,0x37,0xc9,0x15,0xa5,0x4d,0x88,0x5a,0x1a,0x10,0xac,0xa5,0xbe,0xeb,0x74,0xa6,0x05,0x67,0x9e,0x78,0x72,0x8f,0x22,0x78,0x6f,0x2f,0xb9,0x96,0x8f,0x13,0x57,0x88,0x4c,0x9f,0x67,0x37,0xe2,0x67,0x0d,0x4a,0xe8,0x30,0xde,0xa5,0xcf,0x19,0x88,0x20,0x82,0x78
};static char dh_except_a_pubkey_768[] = {0x44,0x2a,0xc0,0xc0,0xd0,0x38,0xa4,0x33,0x23,0x1c,0x52,0x17,0xdd,0x9d,0x91,0x03,0x75,0xc7,0x51,0xe3,0x86,0x1d,0x11,0xad,0xdf,0x6d,0x6f,0x2c,0xf4,0x9b,0x0e,0x62,0x86,0x22,0xdc,0x35,0x1b,0x91,0x45,0x63,0x3a,0x10,0xbc,0x94,0xd9,0xf7,0xb2,0x65,0x2e,0x62,0x03,0x9e,0x5f,0x65,0x4a,0xa1,0x91,0x44,0x0b,0x32,0x81,0xf1,0x6f,0x1b,0x58,0xe7,0xa6,0x79,0xd6,0x30,0xf4,0xd0,0xc9,0xbc,0x52,0x1a,0xf9,0x34,0x39,0x68,0xcf,0x7b,0x14,0x84,0x57,0x32,0xf0,0x4a,0xbf,0x03,0xc6,0x48,0x19,0x35,0xde,0xab
};static char dh_pb_768[] = {0xa5,0x2b,0xb2,0x89,0xd6,0xc9,0x1a,0x25,0x2f,0xca,0x89,0x52,0x51,0x2a,0x00,0x1e,0xd9,0x3d,0x92,0x50,0x58,0xa3,0x8e,0x23,0x7a,0x98,0x85,0xe1,0x5b,0x98,0x06,0x2f,0x7e,0xd2,0x21,0x01,0xa4,0x67,0xc9,0x5a,0x1a,0x12,0x9c,0x96,0x4a,0x08,0x75,0x8c,0xb9,0xb4,0x46,0xc1,0x62,0x76,0xbc,0xdb,0xe9,0xdd,0xbc,0x2d,0x5e,0x78,0x90,0xe7,0x52,0x50,0x27,0x3c,0xad,0x88,0x9c,0xc3,0xac,0x8b,0x91,0x52,0x7f,0x10,0x35,0xb2,0xb5,0x20,0x8f,0x6b,0x81,0xab,0xbe,0x07,0x1c,0x8e,0x42,0x9d,0x16,0x9e,0x65,0xdb
};static char dh_xb_768[] = {0x5b,0xe7,0xa0,0xd2,0xd2,0xd0,0x25,0x83,0x5a,0xe2,0x35,0x20,0x05,0x61,0x51,0x42,0x2a,0x8d,0x89,0xd8,0x94,0x85,0x84,0x42,0x3d,0x09,0x6a,0x18,0x1e,0x7a,0x71,0xa0,0xb6,0x33,0x67,0x24,0x59,0x8d,0x21,0x2d,0x16,0xfa,0x0b,0x20,0x5b,0x14,0x9f,0x69,0x2c,0x56,0xce,0x67,0xeb,0x6d,0x11,0x25,0x45,0x94,0x13,0x5f,0x49,0x77,0xc3,0x36,0x07,0x90,0xad,0xbf,0xa5,0xb8,0x04,0x54,0x42,0xdb,0xfa,0xfa,0x43,0x05,0x41,0xe0,0xa5,0x87,0xd3,0x59,0x3e,0x2a,0xb0,0x8c,0x47,0x6f,0x27,0xc0,0x07,0x27,0x97,0x04
};static char dh_except_b_pubkey_768[] = {0x73,0xf7,0x1a,0xd1,0x2a,0xd0,0xe0,0x0e,0xf6,0xee,0x74,0xfd,0x3a,0xb5,0xd2,0xca,0xb8,0x23,0xe4,0xce,0xc3,0x9a,0xbb,0xe8,0x9b,0xbf,0x67,0xbf,0x0f,0x51,0xe6,0x7d,0x20,0x12,0xf9,0x84,0x99,0xf6,0xd3,0xae,0xbf,0x7a,0x32,0x94,0x2d,0xb5,0x97,0x3b,0x12,0xf9,0x03,0xcd,0x89,0xb6,0xdf,0xb8,0x6b,0x00,0xc3,0x1d,0x44,0x8c,0x28,0xa0,0xd2,0x4a,0x76,0xeb,0x86,0x32,0x7b,0xa6,0x39,0x49,0x8e,0x7b,0x3a,0x3e,0xe5,0x75,0x07,0xaf,0x27,0x27,0xd1,0xdd,0x5d,0x16,0xd7,0x2c,0x3b,0x7e,0x5d,0x8e,0x78,0x2e
};static char dh_share_key_768[] = {0x64,0x01,0xfa,0x30,0x1c,0x96,0x7a,0x51,0xe7,0x53,0x8b,0xda,0x78,0x79,0xa1,0xce,0xea,0x63,0x91,0x89,0xea,0xce,0xe2,0x41,0xc2,0x85,0x1f,0x2d,0xd1,0xbf,0xca,0x22,0x7c,0x11,0x3e,0x69,0xb9,0x59,0x20,0x95,0x5b,0xe2,0x96,0xf7,0x39,0x69,0xe8,0xb2,0x65,0xac,0xa2,0x7f,0x2c,0x7b,0x7b,0x54,0xa4,0x44,0xd7,0xa1,0xc7,0xf3,0x38,0xde,0x11,0x03,0xbf,0x53,0x7e,0x4e,0x37,0x17,0x26,0x8a,0xc3,0x92,0x7c,0x83,0x2c,0xcb,0xd1,0xb3,0xd8,0x96,0x7d,0x0f,0x35,0x6c,0x47,0x6a,0x30,0xde,0x25,0x66,0x29,0x3d
};int main()
{int key_bits = 768;int ret;// 构造DH数据结构DH *d1 = NULL;d1=DH_new();BIGNUM *p, *g, *pri1;p  = BN_bin2bn(dh_pa_768, sizeof(dh_pa_768), NULL);g = BN_bin2bn(dh_g_2, sizeof(dh_g_2), NULL);pri1 = BN_bin2bn(dh_xa_768, sizeof(dh_xa_768), NULL);BIGNUM *t_p = NULL, *t_g = NULL;t_p=BN_dup(p);t_g=BN_dup(g);DH_set0_pqg(d1, t_p, NULL, t_g);DH_set0_key(d1, NULL, pri1);ret=DH_generate_key(d1);if(ret!=1){printf("DH_generate_key err!\n");return -1;}// 获取d1的p,g,pub_key,pri_keyconst BIGNUM *d1p = NULL, *d1g = NULL;DH_get0_pqg(d1, &d1p, NULL, &d1g);const BIGNUM *d1pub_key = NULL, *d1priv_key = NULL;DH_get0_key(d1, &d1pub_key, &d1priv_key);print_bigdata(d1p,"d1p");print_bigdata(d1pub_key,"d1pub_key");print_bigdata(d1priv_key,"d1priv_key");DH *d2 = NULL;d2=DH_new();BIGNUM *pub2,*pri2;pub2 = BN_bin2bn(dh_except_b_pubkey_768, sizeof(dh_except_b_pubkey_768), NULL);pri2 = BN_bin2bn(dh_xb_768, sizeof(dh_xb_768), NULL);DH_set0_pqg(d2, t_p, NULL, t_g);DH_set0_key(d2, pub2, pri2);ret=DH_generate_key(d2);if(ret!=1){printf("DH_generate_key err!\n");return -1;}// 获取d2的p,g,pub_key,pri_keyconst BIGNUM *d2p = NULL, *d2g = NULL;DH_get0_pqg(d2, &d2p, NULL, &d2g);const BIGNUM *d2pub_key = NULL, *d2priv_key = NULL;DH_get0_key(d2, &d2pub_key, &d2priv_key);print_bigdata(d2p,"d2p");print_bigdata(d2pub_key,"d2pub_key");print_bigdata(d2priv_key,"d2priv_key");// 计算共享密钥:d1+d2pub_key,d2+d1pub_key生成相同的共享密钥unsigned char sharekey1[1024] = {0};unsigned char sharekey2[1024] = {0};int len1=DH_compute_key(sharekey1,d2pub_key,d1);int len2=DH_compute_key(sharekey2,d1pub_key,d2);if(len1!=len2){printf("生成共享密钥失败\n");return -1;}if(memcmp(sharekey1,sharekey2,len1)!=0){printf("生成共享密钥失败\n");return -1;}print_hexdata(sharekey1, len1, "sharekey1");print_hexdata(sharekey2, len2, "sharekey2");return 0;
}

openssl编程-DH相关推荐

  1. 《openssl 编程》之 DH

    第十九章DH 19.1  DH算法介绍 DH算法是W.Diffie和M.Hellman提出的.此算法是最早的公钥算法.它实质是一个通信双方进行密钥协商的协议:两个实体中的任何一个使用自己的私钥和另一实 ...

  2. openssl 编程。 证书制作

    首页 博客 学院 下载 GitChat TinyMind 论坛 问答 商城 VIP 活动 写博客 发Chat 登录注册 么刚的专栏 RSS订阅 原 openssl证书制作及编程 2010年07月29日 ...

  3. OpenSSL 编程 二:搭建 CA

    一.证书 证书 – 为公钥加上数字签名 二.证书标准规范X.509 证书是由认证机构颁发的,使用者需要对证书进行验证,因此如果证书的格式千奇百怪那就不方便了.于是,人们制定了证书的标准规范,其中使用最 ...

  4. 《openssl 编程》之 RSA(转)

    17.1  RSA介绍 RSA算法是一个广泛使用的公钥算法.其密钥包括公钥和私钥.它能用于数字签名.身份认证以及密钥交换.RSA密钥长度一般使用1024位或者更高.RSA密钥信息主要包括[1]: Ø  ...

  5. 《openssl 编程》之错误处理

    第十四章   错误处理 14.1  概述 程序设计时,一般通过函数的返回值来判断是否调用成功.设计良好的函数以及好的错误处理能帮助调用者快速找到错误原因.错误处理应该尽可能多的包含各种信息,包括: Ø ...

  6. 《openssl 编程》之数据压缩

    16.1 简介 数据压缩是将原有数据通过某种压缩算法计算得到相对数据量小的过程.这种过程是可逆的,即能通过压缩后的数据恢复出原数据.数据压缩能够节省存储空间,减轻网络负载. 在即需要加密又需要压缩的情 ...

  7. 《openssl 编程》之文本数据库

    第十章   文本数据库 10.1  概述 Openss实现了一个简单的文本数据库,它可以从文件读取数据和将数据写到文件中,并且可以根据关键字段来查询数据.Openssl的文本数据库供apps/目录下的 ...

  8. 《openssl编程》之配置文件

    第八章 配置文件 8.1 概述 Openssl采用自定义的配置文件来获取配置信息.Openssl的配置文件主要由如下内容组成: 注释信息,注释信息由#开头: 段信息,段信息由[xxx]来表示,其中xx ...

  9. 《openssl编程》之BIO

    第七章   抽象IO 7.1    openssl抽象IO openssl抽象IO(I/O abstraction,即BIO)是openssl对于io类型的抽象封装,包括:内存.文件.日志.标准输入输 ...

  10. 《openssl编程》之基础知识

    第一章 基础知识 1.1 对称算法 对称算法使用一个密钥.给定一个明文和一个密钥,加密产生密文,其长度和明文大致相同.解密时,使用读密钥与加密密钥相同. 对称算法主要有四种加密模式: (1) 电子密码 ...

最新文章

  1. 如何判断应用已经安装,如何判断Service,BroastCastReceiver,ContentProvider是否存在...
  2. 恶意软件、Rootkit和僵尸网络
  3. leetcode-15-三数之和
  4. linux小知识之终端
  5. Linux中以单容器部署Nginx+ASP.NET Core
  6. visual studio enter键代码自动补全
  7. KVM之Live Migration
  8. android 碎片问题,Android碎片问题
  9. gnuTLS 提供的 DTLS-API
  10. eclipse中无法新建Android工程 出现问题:Plug-in org.eclipse.ajdt.ui was unable to load
  11. Lagrangian乘子法 对偶问题 KKT条件 Slater条件 与凸优化
  12. Mapx 具体使用方法
  13. Tableau Desktop Pro中文破解版
  14. 点云数据集汇总整理(匠心之作,附官方下载地址)
  15. access和filemaker_四个替代微软Access的开源产品
  16. 机器学习算法工程师面试问题汇总(持续更新)
  17. 类对象初始化和Initializer_list的
  18. 诗词-已然绿盈盈蓝点缀
  19. JS中的各种遍历方法
  20. codejam round1c第二题

热门文章

  1. linux 登录qq虚拟机,不能输入中文
  2. 网站的PV是什么意思
  3. 学习Java第一天笔记
  4. Unity3D之太空大战一
  5. 兴业银行紧急核查国美贷款
  6. 丹阳眼镜购买攻略,其它城市可以此参考
  7. 其实你不懂我的芯--SIM卡的前世今生
  8. 组件化与插件化的差别在哪里?醍醐灌顶!
  9. 德州大学达拉斯分校计算机专业博士,德克萨斯大学达拉斯分校计算机科学理科硕士入学条件及实习就业...
  10. 多变量之间的关系可视化——Seaborn.pairplot