ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

OpenSSL之Diffie-Hellman

2021-11-29 22:33:24  阅读:161  来源: 互联网

标签:std Hellman get OpenSSL vector key diffie Diffie hellman


// diffie_hellman.hpp
#pragma once
#include <openssl/dh.h>
#include <memory>
#include <vector>

namespace crypto {
	class diffie_hellman {
	public:
		diffie_hellman();
		~diffie_hellman() = default;

		bool create_p_g();
		bool set_p_g(const std::vector<std::uint8_t>& p, const std::vector<std::uint8_t>& g);

		std::vector<std::uint8_t> get_shared_p() const;
		std::vector<std::uint8_t> get_shared_g() const;
		std::vector<std::uint8_t> get_pub_key() const;
		std::vector<std::uint8_t> get_pri_key(const std::vector<std::uint8_t>& pub_key) const;

	private:
		std::unique_ptr<DH, decltype(&DH_free)> dh_;
	};
}

// diffie_hellman.cpp
#include "diffie_hellman.hpp"
#include <openssl/bn.h>

namespace crypto {
	namespace {
		std::vector<std::uint8_t> bignum_to_bytes(const BIGNUM* bn) {
			std::vector<std::uint8_t> result(BN_num_bytes(bn));
			BN_bn2bin(bn, result.data());

			return result;
		}

		std::unique_ptr<BIGNUM, decltype(&BN_free)> bytes_to_big_num(const std::vector<std::uint8_t>& uint8_ts) {
			return std::unique_ptr<BIGNUM, decltype(&BN_free)>{ BN_bin2bn(uint8_ts.data(), uint8_ts.size(), nullptr), &BN_free };
		}
	}


	diffie_hellman::diffie_hellman() : dh_ { DH_new(), & DH_free } {
	}

	bool diffie_hellman::create_p_g() {
		constexpr int key_bits{ 512 };

		if (DH_generate_parameters_ex(dh_.get(), key_bits, DH_GENERATOR_2, nullptr) != 1)  {
			return false;
		}
		return DH_generate_key(dh_.get()) == 1;
	}

	bool diffie_hellman::set_p_g(const std::vector<std::uint8_t>& p, const std::vector<std::uint8_t>& g) {
		auto p_bn = BN_bin2bn(p.data(), p.size(), nullptr);
		auto g_bn = BN_bin2bn(g.data(), g.size(), nullptr);

		if (DH_set0_pqg(dh_.get(), p_bn, nullptr, g_bn) != 1) {
			return false;
		}
		return DH_generate_key(dh_.get()) == 1;
	}

	std::vector<std::uint8_t> diffie_hellman::get_shared_p() const {
		return bignum_to_bytes(DH_get0_p(dh_.get()));
	}

	std::vector<std::uint8_t> diffie_hellman::get_shared_g() const {
		return bignum_to_bytes(DH_get0_g(dh_.get()));
	}

	std::vector<std::uint8_t> diffie_hellman::get_pub_key() const {
		return bignum_to_bytes(DH_get0_pub_key(dh_.get()));
	}


	std::vector<std::uint8_t> diffie_hellman::get_pri_key(const std::vector<std::uint8_t>& pub_key) const {
		auto pub_key_bn{ bytes_to_big_num(pub_key) };

		std::vector<std::uint8_t> result(DH_size(dh_.get()));
		const int ret = DH_compute_key(result.data(), pub_key_bn.get(), dh_.get());

		return ret < 0 ? std::vector<std::uint8_t>{} : result;
	}
}

// main.cpp
#include "diffie_hellman.hpp"
#include <cassert>

int main()
{
	crypto::diffie_hellman request;
	assert(request.create_p_g());
	auto p = request.get_shared_p();
	auto g = request.get_shared_g();
	auto&& pubkey_of_request = request.get_pub_key();

	crypto::diffie_hellman response;
	assert(response.set_p_g(p, g));
	auto&& pubkey_of_response = response.get_pub_key();

	auto&& key1 = request.get_pri_key(pubkey_of_response);
	auto&& key2 = response.get_pri_key(pubkey_of_request);

	assert(key1 == key2);

	return 0;
}

标签:std,Hellman,get,OpenSSL,vector,key,diffie,Diffie,hellman
来源: https://blog.csdn.net/kpengk/article/details/121620934

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有