QT版本基于OpenSSL3的ECDH密钥交换算法
  qjOESHUzOCRJ 2023年11月02日 31 0
项目地址Gitee地址

​Gitee地址​

介绍

QT版本基于OpenSSL3的ECDH密钥交换算法

OpenSSL版本

3.0.8

QT版本

5.14.1

主要代码
#ifndef QECDHMGR_H
#define QECDHMGR_H

#include <QString>
#include <QByteArray>
#include <QDebug>
#include <QScopedPointer>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/core_names.h>
#include <openssl/param_build.h>
#include <openssl/evp.h>
#include <openssl/ec.h>
#include <openssl/param_build.h>
#include <openssl/bn.h>


class QECDHMgr
{
public:
QECDHMgr();

// 获取最后一次错误信息
QString GetLastError();

// 设置CurveName,可以为secp384r1等
// 系统不支持的加密方式返回false
bool SetCurveName(QString curveName);

// 获取CurevName
QString GetCurveName();

// 生成密钥对(包含公钥和私钥)
bool GenerateKeys();

// 获取私钥
QString GetPrivateKey(); // for debug

// 获取公钥
QString GetPublicKey();

// 设置私钥
bool SetPrivateKey(QString hexPrivateKey);

// 设置公钥
bool SetPublicKey(QString hexPublicKey);

// 设置公钥、私钥对
bool SetKeyPair(QString hexPublicKey, QString hexPrivateKey);

// 生成对称密钥
QString DeriveSharedSecret(QString hexPeerPublicKey);

private:

static int GetHexValue(unsigned char hexDigit)
{
static constexpr char hexValues[256] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
return hexValues[hexDigit];
}

// this struct calls "OSSL_PARAM_BLD_free" to delete the pointer
struct ScopedPointerParamBldDeleter
{
static inline void cleanup(OSSL_PARAM_BLD *pointer)
{
OSSL_PARAM_BLD_free(pointer);
}
};

// this struct calls "OSSL_PARAM_BLD_free" to delete the pointer
struct ScopedPointerParamDeleter
{
static inline void cleanup(OSSL_PARAM *pointer)
{
OSSL_PARAM_free(pointer);
}
};

// this struct calls "OSSL_PARAM_BLD_free" to delete the pointer
struct ScopedPointerKeyCtxDeleter
{
static inline void cleanup(EVP_PKEY_CTX *pointer)
{
EVP_PKEY_CTX_free(pointer);
}
};

// this struct calls "OSSL_PARAM_BLD_free" to delete the pointer
struct ScopedPointerKeyDeleter
{
static inline void cleanup(EVP_PKEY *pointer)
{
EVP_PKEY_free(pointer);
}
};

// Converts a hex string to BIGNUM.
BIGNUM* ConvertHexToBigNum(QString hexBigNum);

// Converts BIGNUM to a hex string.
// Returns an empty string if convertion fails.
QString ConvertBigNumToHex(const BIGNUM* bigNum);

// Converts binary data to a hex string.
QString ConvertDataToHex(QByteArray data);

// Converts a hex string to binary data.
QByteArray ConvertHexToData(QString hex);

// Create a Peer public key
bool CreatePeerPublicKey(QString hexPeerPublicKey, QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter>* peerPublicKey);

// Create a Peer private key
bool CreatePeerPrivateKey(QString hexPeerPrivateKey, QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter>* peerPrivateKey);

// Create a Peer key pair
bool CreatePeerKeyPair(QString hexPeerPublicKey, QString hexPeerPrivateKey, QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter>* peerPrivateKey);


private:

QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter> keyPair_;

QString curveName_;
};

#endif // QECDHMGR_H
#include "qdhmgr.h"

QECDHMgr::QECDHMgr()
{

}

QString QECDHMgr::GetCurveName()
{
return this->curveName_;
}

bool QECDHMgr::SetCurveName(QString curveName)
{
EC_builtin_curve * buffer = nullptr;

size_t count = EC_get_builtin_curves(nullptr, 0);
if (count <= 0) {
return false;
}

buffer = new EC_builtin_curve[count];
if (EC_get_builtin_curves(buffer, count) != count) {
return false;
}

// Check if the curve is in the list.
for (int i = 0; i < count; ++i) {
const char* shortName = OBJ_nid2sn(buffer[i].nid);
const char* comment = buffer[i].comment;
if (shortName && strlen(shortName) > 0) {
// qDebug() << buffer[i].nid << "|"<< shortName<<"|" << comment;
if(curveName == QString(shortName))
{
curveName_ = curveName;
return true;
}
}
}
return false;
}

bool QECDHMgr::GenerateKeys()
{
ERR_clear_error();

// First, create an OSSL_PARAM_BLD.
QScopedPointer <OSSL_PARAM_BLD , ScopedPointerParamBldDeleter> paramBuild(OSSL_PARAM_BLD_new());
if (!paramBuild.data())
{
return false;
}

// Push the curve name to the OSSL_PARAM_BLD.
if (!OSSL_PARAM_BLD_push_utf8_string(paramBuild.data(), OSSL_PKEY_PARAM_GROUP_NAME, curveName_.toStdString().c_str(), 0)) {
return false;
}

// Convert OSSL_PARAM_BLD to OSSL_PARAM.
QScopedPointer <OSSL_PARAM , ScopedPointerParamDeleter> params(OSSL_PARAM_BLD_to_param(paramBuild.data()));
if (!params.data()) {
return false;
}

// Create the EC key generation context.
QScopedPointer <EVP_PKEY_CTX , ScopedPointerKeyCtxDeleter> ctx(EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr));
if (!ctx.data())
{
return false;
}

// Initialize the key generation context.
if (EVP_PKEY_keygen_init(ctx.data()) <= 0) {
return false;
}

// Set the parameters which include the curve name.
if (!EVP_PKEY_CTX_set_params(ctx.data(), params.data())) {
return false;
}

// Generate a key pair.
EVP_PKEY* keyPair = nullptr;
if (EVP_PKEY_generate(ctx.data(), &keyPair) <= 0) {
return false;
}
keyPair_.reset(keyPair);
return true;
}

QString QECDHMgr::GetPrivateKey()
{
ERR_clear_error();

if(keyPair_.data())
{
// The private key is stored as a BIGNUM object.
BIGNUM* privateKey = nullptr;
if (!EVP_PKEY_get_bn_param(keyPair_.data(), OSSL_PKEY_PARAM_PRIV_KEY, &privateKey)) {
return "";
}

// Convert the BIGNUM to a hex string.
QString hexPrivateKey = ConvertBigNumToHex(privateKey);
BN_free(privateKey);
return hexPrivateKey;
}else
{
return "";
}
}

QString QECDHMgr::GetPublicKey()
{
ERR_clear_error();
if(keyPair_.data())
{
// The public key is stored as a byte array.
// Get the array size.
size_t keyLength = 0;
if (!EVP_PKEY_get_octet_string_param(keyPair_.data(), OSSL_PKEY_PARAM_PUB_KEY, nullptr, 0, &keyLength)) {
return "";
}

// Get the key.
unsigned char * publicKey = new unsigned char [keyLength];
if (!EVP_PKEY_get_octet_string_param(keyPair_.data(), OSSL_PKEY_PARAM_PUB_KEY, publicKey, keyLength, &keyLength)) {
return "";
}

// Convert the byte array key to a hex string.
QString hexPublicKey = ConvertDataToHex(QByteArray((char *)publicKey, keyLength));
delete [] publicKey;
publicKey = nullptr;
return hexPublicKey;
}else
{
return "";
}
}

bool QECDHMgr::SetPublicKey(QString hexPublicKey)
{
QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter> peerPublicKey;
if(!CreatePeerPublicKey(hexPublicKey, &peerPublicKey))
{
return false;
}

keyPair_.reset(peerPublicKey.take());
return true;
}

bool QECDHMgr::SetPrivateKey(QString hexPrivateKey)
{
QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter> peerPrivateKey;
if(!CreatePeerPrivateKey(hexPrivateKey, &peerPrivateKey))
{
return false;
}
keyPair_.reset(peerPrivateKey.take());
return true;
}

bool QECDHMgr::SetKeyPair(QString hexPublicKey, QString hexPrivateKey)
{
QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter> peerKeyPair;
if(!CreatePeerKeyPair(hexPublicKey, hexPrivateKey, &peerKeyPair))
{
return false;
}
keyPair_.reset(peerKeyPair.take());
return true;
}

QString QECDHMgr::DeriveSharedSecret(QString hexPeerPublicKey)
{
ERR_clear_error();

// First, you have to create the peer public key object.
// It takes several calls, so it is done in a separate function.
QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter> peerPublicKey;
if(!CreatePeerPublicKey(hexPeerPublicKey, &peerPublicKey))
{
return "";
}

// Create the derivation context.
QScopedPointer <EVP_PKEY_CTX , ScopedPointerKeyCtxDeleter> derivationCtx(EVP_PKEY_CTX_new(keyPair_.data(), nullptr));
if (!derivationCtx.data()) {
return "";
}

// Initialize the derivation context.
if (EVP_PKEY_derive_init(derivationCtx.data()) <= 0) {
return "";
}

// Set the peer public key object.
if (EVP_PKEY_derive_set_peer(derivationCtx.data(), peerPublicKey.data()) <= 0) {
return "";
}

// Get the shared secret length.
size_t sharedSecretLength = 0;
if (EVP_PKEY_derive(derivationCtx.data(), nullptr, &sharedSecretLength) <= 0) {
return "";
}

if (sharedSecretLength == 0) {
return "";
}

unsigned char * sharedSecret = new unsigned char [sharedSecretLength];
// Derive the shared secret.
if (EVP_PKEY_derive(derivationCtx.data(), sharedSecret, &sharedSecretLength) <= 0) {
return "";
}
// Convert to a hex string.
QString hexSharedSecret = ConvertDataToHex(QByteArray((char *)sharedSecret, sharedSecretLength));
delete [] sharedSecret;

return hexSharedSecret;
}

QString QECDHMgr::GetLastError()
{
unsigned long lastError = ERR_peek_last_error();
if (lastError == 0) {
return "";
}
char errorString[256];
ERR_error_string_n(lastError, errorString, sizeof(errorString));
return errorString;
}
// ***************************** 以下是私有函数 **********************************

QString QECDHMgr::ConvertBigNumToHex(const BIGNUM *bigNum)
{
char* tmpHexBigNum = BN_bn2hex(bigNum);
if (!tmpHexBigNum) {
return "";
}
QString hexBigNum(tmpHexBigNum);
OPENSSL_free(tmpHexBigNum);
return hexBigNum;
}

BIGNUM* QECDHMgr::ConvertHexToBigNum(QString hexBigNum)
{
BIGNUM* bn = nullptr;
if (!BN_hex2bn(&bn, hexBigNum.toStdString().c_str())) {
return nullptr;
}
return bn;
}

QString QECDHMgr::ConvertDataToHex(QByteArray data)
{
static const char hexDigits[] = "0123456789ABCDEF";

QString hex;
hex.reserve(data.size() * 2);

for (unsigned char c : data) {
hex.push_back(hexDigits[c >> 4]);
hex.push_back(hexDigits[c & 15]);
}

return hex;
}

// Converts a hex string to binary data.
QByteArray QECDHMgr::ConvertHexToData(QString hex)
{
QByteArray data;
// Must be an even number!
if (hex.size() & 1) {
return data;
}

auto it = hex.begin();
while (it != hex.end()) {
int hi = GetHexValue((*it++).toLatin1());
int lo = GetHexValue((*it++).toLatin1());
if (hi == -1 || lo == -1) {
data.clear();
return data;
}
data.push_back(hi << 4 | lo);
}

return data;
}

bool QECDHMgr::CreatePeerPublicKey(QString hexPeerPublicKey, QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter>* peerPublicKey)
{
ERR_clear_error();

// First, we sould create an OSSL_PARAM_BLD with the curve name
// and the raw peer public key.
QScopedPointer <OSSL_PARAM_BLD, ScopedPointerParamBldDeleter> paramBuild(OSSL_PARAM_BLD_new());
if (!paramBuild.data()) {
return false;
}

// Set the curve name.
if (!OSSL_PARAM_BLD_push_utf8_string(paramBuild.data(), OSSL_PKEY_PARAM_GROUP_NAME,curveName_.toStdString().c_str(), 0)) {
return false;
}

// Convert the peer hex public key to raw data.
QByteArray binPeerPublicKey = ConvertHexToData(hexPeerPublicKey);
if (binPeerPublicKey.size() <= 0) {
return false;
}

// Set the raw peer public key.
if (!OSSL_PARAM_BLD_push_octet_string(paramBuild.data(), OSSL_PKEY_PARAM_PUB_KEY, binPeerPublicKey.data(), binPeerPublicKey.size())) {
return false;
}

// Convert the OSSL_PARAM_BLD to OSSL_PARAM.
QScopedPointer <OSSL_PARAM , ScopedPointerParamDeleter> params(OSSL_PARAM_BLD_to_param(paramBuild.data()));
if (!params.data()) {
return false;
}

// Create a EVP_PKEY context.
QScopedPointer <EVP_PKEY_CTX , ScopedPointerKeyCtxDeleter> peerPublicKeyCtx(EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr));
if (!peerPublicKeyCtx.data()) {
return false;
}

// Initialize the context.
if (EVP_PKEY_fromdata_init(peerPublicKeyCtx.data()) <= 0) {
return false;
}

// Create the peer public key object.
EVP_PKEY* tmp = nullptr;
if (EVP_PKEY_fromdata(peerPublicKeyCtx.data(), &tmp, EVP_PKEY_PUBLIC_KEY, params.data()) <= 0) {
return false;
}
peerPublicKey->reset(tmp);
return true;
}

bool QECDHMgr::CreatePeerPrivateKey(QString hexPeerPrivateKey, QScopedPointer <EVP_PKEY , ScopedPointerKeyDeleter>* peerPrivateKey)
{
ERR_clear_error();

// First, we sould create an OSSL_PARAM_BLD with the curve name
// and the raw peer public key.
QScopedPointer <OSSL_PARAM_BLD, ScopedPointerParamBldDeleter> paramBuild(OSSL_PARAM_BLD_new());
if (!paramBuild.data()) {
return false;
}

// Set the curve name.
if (!OSSL_PARAM_BLD_push_utf8_string(paramBuild.data(), OSSL_PKEY_PARAM_GROUP_NAME,curveName_.toStdString().c_str(), 0)) {
return false;
}

// Convert the peer hex private key to raw data.
BIGNUM * binPeerPrivateKey = ConvertHexToBigNum(hexPeerPrivateKey);
if(!binPeerPrivateKey)
{
return false;
}

// Set the raw peer private key.
if (!OSSL_PARAM_BLD_push_BN(paramBuild.data(), OSSL_PKEY_PARAM_PRIV_KEY, binPeerPrivateKey)) {
return false;
}

// Convert the OSSL_PARAM_BLD to OSSL_PARAM.
QScopedPointer <OSSL_PARAM , ScopedPointerParamDeleter> params(OSSL_PARAM_BLD_to_param(paramBuild.data()));
if (!params.data()) {
return false;
}

// Create a EVP_PKEY context.
QScopedPointer <EVP_PKEY_CTX , ScopedPointerKeyCtxDeleter> peerPrivateKeyCtx(EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr));
if (!peerPrivateKeyCtx.data()) {
return false;
}

// Initialize the context.
if (EVP_PKEY_fromdata_init(peerPrivateKeyCtx.data()) <= 0) {
return false;
}

// Create the peer private key object.
EVP_PKEY* tmp = nullptr;
if (EVP_PKEY_fromdata(peerPrivateKeyCtx.data(), &tmp, EVP_PKEY_KEYPAIR, params.data()) <= 0) {
return false;
}
peerPrivateKey->reset(tmp);
return true;
}

bool QECDHMgr::CreatePeerKeyPair(QString hexPeerPublicKey, QString hexPeerPrivateKey, QScopedPointer<EVP_PKEY, ScopedPointerKeyDeleter> *peerPrivateKey)
{
ERR_clear_error();

// First, we sould create an OSSL_PARAM_BLD with the curve name
// and the raw peer public key.
QScopedPointer <OSSL_PARAM_BLD, ScopedPointerParamBldDeleter> paramBuild(OSSL_PARAM_BLD_new());
if (!paramBuild.data()) {
return false;
}

// Set the curve name.
if (!OSSL_PARAM_BLD_push_utf8_string(paramBuild.data(), OSSL_PKEY_PARAM_GROUP_NAME,curveName_.toStdString().c_str(), 0)) {
return false;
}

// Convert the peer hex private key to raw data.
BIGNUM * binPeerPrivateKey = ConvertHexToBigNum(hexPeerPrivateKey);
if(!binPeerPrivateKey)
{
return false;
}

// Set the raw peer private key.
if (!OSSL_PARAM_BLD_push_BN(paramBuild.data(), OSSL_PKEY_PARAM_PRIV_KEY, binPeerPrivateKey)) {
return false;
}

// Convert the peer hex public key to raw data.
QByteArray binPeerPublicKey = ConvertHexToData(hexPeerPublicKey);
if (binPeerPublicKey.size() <= 0) {
return false;
}

// Set the raw peer public key.
if (!OSSL_PARAM_BLD_push_octet_string(paramBuild.data(), OSSL_PKEY_PARAM_PUB_KEY, binPeerPublicKey.data(), binPeerPublicKey.size())) {
return false;
}

// Convert the OSSL_PARAM_BLD to OSSL_PARAM.
QScopedPointer <OSSL_PARAM , ScopedPointerParamDeleter> params(OSSL_PARAM_BLD_to_param(paramBuild.data()));
if (!params.data()) {
return false;
}

// Create a EVP_PKEY context.
QScopedPointer <EVP_PKEY_CTX , ScopedPointerKeyCtxDeleter> peerPrivateKeyCtx(EVP_PKEY_CTX_new_from_name(nullptr, "EC", nullptr));
if (!peerPrivateKeyCtx.data()) {
return false;
}

// Initialize the context.
if (EVP_PKEY_fromdata_init(peerPrivateKeyCtx.data()) <= 0) {
return false;
}

// Create the peer private key object.
EVP_PKEY* tmp = nullptr;
if (EVP_PKEY_fromdata(peerPrivateKeyCtx.data(), &tmp, EVP_PKEY_KEYPAIR, params.data()) <= 0) {
return false;
}
peerPrivateKey->reset(tmp);
return true;
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>


MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);


QECDHMgr qECDHMgrA,qECDHMgrB;
QString pubA, priA, pubB, priB;

// *****************
// * 【测试1】
// * 产生A的密钥对
// *****************
if(qECDHMgrA.SetCurveName("secp384r1"))
{
if(qECDHMgrA.GenerateKeys())
{
pubA = qECDHMgrA.GetPublicKey();
priA = qECDHMgrA.GetPrivateKey();
qDebug() << "PublicKeyA" << pubA;
qDebug() << "PrivateKeyA" << priA;
}else
{
qDebug() << "GenerateKeys fail" ;
}
}else
{
qDebug() << "The curve is not supported.";
}

// *****************
// * 【测试2】
// * 产生B的密钥对
// *****************
if(qECDHMgrB.SetCurveName("secp384r1"))
{
if(qECDHMgrB.GenerateKeys())
{
pubB = qECDHMgrB.GetPublicKey();
priB = qECDHMgrB.GetPrivateKey();
qDebug() << "PublicKeyB" << pubB;
qDebug() << "PrivateKeyB" << priB;
}else
{
qDebug() << "GenerateKeys fail" ;
}
}else
{
qDebug() << "The curve is not supported.";
}

qDebug() << "*********************************";

// *****************
// * 【测试3】
// * 分别载入公钥、私钥
// *****************
QECDHMgr qECDHMgrA1;
if(qECDHMgrA1.SetCurveName("secp384r1"))
{
// 写入公钥
if(qECDHMgrA1.SetPublicKey(pubA))
{
qDebug() << "PublicKeyA1" << qECDHMgrA1.GetPublicKey();
}else
{
qDebug() << "set pubkeyA1 Error" << qECDHMgrA1.GetLastError();
}

// 写入私钥
if(qECDHMgrA1.SetPrivateKey(priA))
{
qDebug() << "PrivateKeyA1" << qECDHMgrA1.GetPrivateKey();
QString secA1 = qECDHMgrA1.DeriveSharedSecret(pubB);
qDebug() << "SecKeyA1" << secA1;
}else
{
qDebug() << "set prikeyA1 Error" << qECDHMgrA1.GetLastError();
}
}else
{
qDebug() << "The curve is not supported.";
}

qDebug() << "*********************************";


// *****************
// * 【测试4】
// * 一次性载入密钥对(包含公钥和私钥)
// *****************
QECDHMgr qECDHMgrA2;
if(qECDHMgrA2.SetCurveName("secp384r1"))
{
if(qECDHMgrA2.SetKeyPair(pubA, priA))
{
qDebug() << "PrivateKeyA3" << qECDHMgrA2.GetPrivateKey();
qDebug() << "PublicKeyA3" << qECDHMgrA2.GetPublicKey();
}else
{
qDebug() << "set prikeyA3 Error" << qECDHMgrA2.GetLastError();
}
}else
{
qDebug() << "The curve is not supported.";
}


qDebug() << "*********************************";

// *****************
// * 【测试5】
// * 生成对称密钥
// *****************
QECDHMgr qECDHMgrA3, qECDHMgrB3;
if(qECDHMgrA3.SetCurveName("secp384r1"))
{
if(qECDHMgrA3.SetKeyPair(pubA, priA))
{
qDebug() << "PrivateKeyA3" << qECDHMgrA3.GetPrivateKey();
qDebug() << "PublicKeyA3" << qECDHMgrA3.GetPublicKey();
}else
{
qDebug() << "set prikeyA3 Error" << qECDHMgrA3.GetLastError();
}
}else
{
qDebug() << "The curve is not supported.";
}
if(qECDHMgrB3.SetCurveName("secp384r1"))
{
if(qECDHMgrB3.SetKeyPair(pubB, priB))
{
qDebug() << "PrivateKeyB3" << qECDHMgrB3.GetPrivateKey();
qDebug() << "PublicKeyB3" << qECDHMgrB3.GetPublicKey();
}else
{
qDebug() << "set prikeyB3 Error" << qECDHMgrB3.GetLastError();
}
}else
{
qDebug() << "The curve is not supported.";
}
qDebug() << "SecKeyA3" << qECDHMgrA3.DeriveSharedSecret(pubB);
qDebug() << "SecKeyB3" << qECDHMgrB3.DeriveSharedSecret(pubA);
}

MainWindow::~MainWindow()
{
delete ui;
}

执行效果

QT版本基于OpenSSL3的ECDH密钥交换算法_QT

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  lA9hNJ8xYnRP   2023年12月12日   30   0   0 Qt
  lA9hNJ8xYnRP   2023年12月06日   30   0   0 Qt
  nIBmcPWZzwbL   2023年11月13日   32   0   0 Qt
  nIBmcPWZzwbL   2023年11月13日   43   0   0 Qt
  lA9hNJ8xYnRP   2023年12月06日   34   0   0 构造函数Qt
  lA9hNJ8xYnRP   2023年12月07日   30   0   0 Qt
  lA9hNJ8xYnRP   2023年12月11日   26   0   0 Qt
  lA9hNJ8xYnRP   2023年11月25日   37   0   0 Qt数据
  lA9hNJ8xYnRP   2023年11月30日   29   0   0 Qt表视图
  nIBmcPWZzwbL   2023年11月13日   30   0   0 Qt
  nIBmcPWZzwbL   2023年11月13日   34   0   0 Qt
  nIBmcPWZzwbL   2023年11月13日   44   0   0 Qt