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

项目地址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;
}
执行效果

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值