博客摘录「 《openssl 编程》之 DH」2023年5月26日

(1)DH_new       生成DH数据结构,其DH_METHOD采用openssl默认提供的。

(2)  DH_generate_parameters

              生成DH密钥参数。

临时代码如下:

#include <openssl/bn.h>
#include <openssl/dh.h>
#include <openssl/evp.h>
#include <openssl/err.h>
#include <iostream>
#include <cassert>
using namespace std;
class Request
{
public:
	Request()
	{

		//补全函数,要求生成 DH 数据结构
		m_dh=DH_new();
		//生成 DH 密钥参数
		//DH_check 检查 DH 密钥
		//根据 DH_check 返回结果判断密钥是否符合要求
		int ret;
		ret = DH_generate_parameters_ex(d1, 64, DH_GENERATOR_2, NULL);

		if (ret != 1)

		{
			printf(“DH_generate_parameters_ex err!\n”);

			return -1;

		}

		/* 检查密钥参数 */

		ret = DH_check(d1, &i);

		if (ret != 1)

		{
			printf(“DH_check err!\n”);

			if (i&DH_CHECK_P_NOT_PRIME)

				printf(“p value is not prime\n”);

			if (i&DH_CHECK_P_NOT_SAFE_PRIME)

				printf(“p value is not a safe prime\n”);

			if (i&DH_UNABLE_TO_CHECK_GENERATOR)

				printf(“unable to check the generator value\n”);

			if (i&DH_NOT_SUITABLE_GENERATOR)

				printf(“the g value is not a generator\n”);

		}

		printf(“DH parameters appear to be ok.\n”);
		// 生成 DH 密钥
		/* 生成公私钥 */

		ret = DH_generate_key(d1);

		if (ret != 1)

		{
			printf(“DH_generate_key err!\n”);

			return -1;

		}

		/* p和g为公开的密钥参数,因此可以拷贝 */

		d2->p = BN_dup(d1->p);

		d2->g = BN_dup(d1->g);

		/* 生成公私钥,用于测试生成共享密钥 */

		ret = DH_generate_key(d2);

		if (ret != 1)

		{
			printf(“DH_generate_key err!\n”);

			return -1;

		}

		/* 检查公钥 */

		ret = DH_check_pub_key(d1, d1->pub_key, &i);

		if (ret != 1)

		{
			if (i&DH_CHECK_PUBKEY_TOO_SMALL)

				printf(“pub key too small \n”);

			if (i&DH_CHECK_PUBKEY_TOO_LARGE)

				printf(“pub key too large \n”);

		}
	}
	~Request()
	{
		if (m_dh)
			//释放 DH 数据结构
			DH_free(m_dh);
		
	}
	void GetSharedNums(BIGNUM *&p, BIGNUM *&g)
	{
		assert(m_dh);
		//自行编写代码,要求如下:
		//新建一个 BIGNUM 结构,将 DH_get0_p(m_dh)复制给新建结构返回给 p,错误返回 NULL
		p = DH_get0_p(m_dh);
		//新建一个 BIGNUM 结构,将 DH_get0_g(m_dh)复制给新建结构返回给 g,错误返回 NULL
		g = DH_get0_g(m_dh);
	}
	void GetPubKey(BIGNUM *&pubkey)
	{
		assert(m_dh);
		//自行编写代码,要求如下:
		 //新建一个 BIGNUM 结构,将 DH_get0_pub_key(m_dh)复制给新建结构返回,错误返回 NULL
		pubkey = DH_get0_pub_key(m_dh);
	}
	std::string GetPriKey(const BIGNUM *pubkey)
	{
		
		//编写一段代码,计算共享密钥
		len1=DH_compute_key(sharekey1,d2->pub_key,d1);

	   len2=DH_compute_key(sharekey2,d1->pub_key,d2);
	   
	}
private:
	DH *m_dh;
};


class Response
{
public:
	//构造函数
	Response() : m_dh(NULL) {}
	//析构函数
	~Response()
	{
		if (m_dh)
			//释放 DH 数据结构
			DH_free(m_dh);
	}
	bool Init(BIGNUM *p, BIGNUM *g)
	{
		if (!m_dh)
		{
			m_dh = DH_new();
		}
		/*编写一段代码,设置 response 的参数 p 和 g*/
		
	}
	void GetPubKey(BIGNUM *&pubkey)
	{
		assert(m_dh);
		//DH_get0_priv_key(m_dh)判断结构
		assert(DH_get0_priv_key(m_dh));
		//新建一个 BIGNUM 结构,将 DH_get0_priv_key(m_dh)复制给新建结构返回,错误返回 NULL
		//...这个是啥?
		//编写代码,通过 DH_get0_pub_key 获取公钥
		pubkey = DH_get0_pub_key(m_dh);
	}
	std::string GetPriKey(const BIGNUM *pubkey)
	{
		assert(m_dh);
		//声明变量* key 并分配内存空间
		unsigned char *key = (unsigned char *)malloc(DH_size(m_dh));
		//计算共享密钥,用于数据交换
		int rst = DH_compute_key(key, pubkey, m_dh);
		if (rst < 0)
		{
			cout << "error" << endl;
			printf("%s", ERR_reason_error_string(ERR_get_error()));
		}
		char hex[1024];
		const char mapping_hex_string[] = "0123456789ABCDEF";
		for (int i = 0; i < DH_size(m_dh); i++)
		{
			hex[i * 2] = mapping_hex_string[key[i] >> 4];
			// printf("pDst[i * 2]=%c\n", pDst[i * 2]);
			hex[i * 2 + 1] = mapping_hex_string[key[i] & 15];
			// printf("pDst[i * 2 + 1]=%c\n", pDst[i * 2 + 1]);
		}
		printf("ResponseKey=");
		for (int i = 0; i < 2 * DH_size(m_dh); i++)
		{
			printf("%c", hex[i]);
		}
		printf("\n");
		std::string ret(reinterpret_cast<char *>(key));
		free(key);
		return ret;
	}
private:
	DH *m_dh;
};
8
int main(void)
{
	char hex[1024];
	//新建对象
	DH *m_dh = DH_new();
	//成可在一组用户之间共享的 Diffie-Hellman 参数,并将它们存储在提供的 DH 结构中
	//也可以理解为生成合适的质数
	int rst = DH_generate_parameters_ex(m_dh, 512, 2, NULL);
	//检查 DH 密钥
	rst = DH_check(m_dh, &rst);
	assert(rst == 1);
	const BIGNUM *ppp = DH_get0_p(m_dh);
	BIGNUM *x = BN_dup(ppp);
	//新建 Request 对象,对应流程图中的步骤①
	Request request;
	//初始化指针均为 NULL
	BIGNUM *p = NULL, *g = NULL;
	//新建 BIGNUM 结构
	request.GetSharedNums(p, g);
	//新建 Response 对象,对应流程图中的步骤③
	Response response;
	//初始化
	bool init = response.Init(p, g);
	assert(init);
	//初始化 request 和 response 指针均为 NULL
	BIGNUM *pubkey_of_request = NULL, *pubkey_of_response = NULL;
	//获取 request 公钥
	request.GetPubKey(pubkey_of_request);
	//获取 response 公钥
	response.GetPubKey(pubkey_of_response);
	//获取 request 私钥,对应流程图中的步骤②
	std::string key1 = request.GetPriKey(pubkey_of_response);
	cout << endl;
	//获取 response 私钥,对应流程图中的步骤④
	std::string key2 = response.GetPriKey(pubkey_of_request);
	//判断是私钥是否相同
	int cmp = key1.compare(key2);
	if (cmp == 0)
	{
		cout << "协商后的密钥一致" << endl;
	}
	else
	{
			cout << "协商后的密钥不一致" << endl;
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值