当我为私钥和对等密钥传入字节缓冲区时,OpenSSL ECDH不工作

当我为私钥和对等密钥传入字节缓冲区时,OpenSSL ECDH不工作,openssl,Openssl,我一直在努力让ecdh通过传递字节密钥缓冲区来使用openssl 用于私钥和对等密钥。在线查看,我可以看到如何做ecdh如果钥匙 在ecdh函数中生成。我没有弄明白的是与评论有关的 在示例代码中说,“假设pkey,peerkey已经设置好了。”(我不知道) 请认为我正在正确地设置这些。--我是openssl新手,可能有 我已经生成了两对公共/私有 使用附带的generateAsymmetyKeyPair()函数创建密钥。然后我硬编码这些值 所以每次测试我都可以得到相同的值。(请注意,有一个带前缀

我一直在努力让ecdh通过传递字节密钥缓冲区来使用openssl 用于私钥和对等密钥。在线查看,我可以看到如何做ecdh如果钥匙 在ecdh函数中生成。我没有弄明白的是与评论有关的 在示例代码中说,“假设pkey,peerkey已经设置好了。”(我不知道) 请认为我正在正确地设置这些。--我是openssl新手,可能有 我已经生成了两对公共/私有 使用附带的generateAsymmetyKeyPair()函数创建密钥。然后我硬编码这些值 所以每次测试我都可以得到相同的值。(请注意,有一个带前缀的0x04值 关于公钥(用于压缩)。我发现我没有任何错误 但是每次调用函数时,我得到的ecdh值都是不同的。(我会的 希望得到相同的结果,即使它是错误的。)我的代码包括在内,如果任何人 如果你能提醒我做错了什么,我将不胜感激

    int32_t generateAsymmetricKeyPair(
        int32_t keySizeBits,
        unsigned char* publicKeyData,
        unsigned char* privateKeyData,
        unsigned char* keyIdData)
{
    EC_KEY                  *ecKey          = EC_KEY_new();
    EC_POINT                *ecPoint        = NULL;
    const EC_POINT          *ecPoint2       = NULL;
    EC_GROUP                *ecGroup        = NULL;
    point_conversion_form_t form            = POINT_CONVERSION_UNCOMPRESSED;
    int32_t                 asn1_flag       = OPENSSL_EC_NAMED_CURVE;
    int32_t                 sizePrvKeyBytes = 0;
    int32_t                 sizePubKeyBytes = 0;

    switch(keySizeBits)
    {
        case 256:
            ecGroup = EC_GROUP_new_by_curve_name(OBJ_sn2nid("prime256v1"));
            break;
        case 384:
            ecGroup = EC_GROUP_new_by_curve_name(OBJ_sn2nid("secp384r1"));
            break;
        case 521:
            ecGroup = EC_GROUP_new_by_curve_name(OBJ_sn2nid("secp521r1"));
            break;
        default:
            return 0;
    }

    sizePrvKeyBytes = keySizeBits / 8 + (((keySizeBits % 8) > 0 ) ? 1 : 0);
    sizePubKeyBytes = sizePrvKeyBytes * 2 + 1;

    EC_GROUP_set_asn1_flag(ecGroup, asn1_flag);
    EC_GROUP_set_point_conversion_form(ecGroup, form);
    EC_KEY_set_group(ecKey, ecGroup);

    ecPoint = EC_POINT_new(ecGroup);

    if(EC_KEY_generate_key(ecKey))
    {
        const BIGNUM *bn;

        /* Get Private Key */
        bn = EC_KEY_get0_private_key(ecKey);
        BN_bn2bin(bn, privateKeyData);

        /* Get Public Key */
        ecPoint2 = EC_KEY_get0_public_key(ecKey);
        EC_POINT_point2oct(EC_KEY_get0_group(ecKey),
                ecPoint2,
                POINT_CONVERSION_UNCOMPRESSED,
                publicKeyData,
                sizePubKeyBytes,
                NULL);

        /* Calculate keyId, Ignore format byte[0] */
        SHA1(publicKeyData + 1, sizePubKeyBytes - 1, keyIdData);
    }
    else
    {
        return 0;
    }
    return 1;
}

void deriveSharedSecret(
        unsigned char* pKey,
        unsigned char* peerKey,
        unsigned char* &secretKey,
        size_t* secretLen,
        int32_t privKeySize)
{
    bool                    grpForEc        = true;
    EVP_PKEY_CTX            *sharedCtx;
    EC_KEY                  *ecPrivKey      = NULL;
    EC_KEY                  *ecPeerKey      = NULL;
    EVP_PKEY                *evpPrivKey     = EVP_PKEY_new();
    EVP_PKEY                *evpPeerKey     = EVP_PKEY_new();
    BIGNUM                  *privBN         = BN_new();
    EC_POINT                *ecPubKey       = NULL;
    EC_POINT                *point          = NULL;
    BN_CTX                  *ctx            = BN_CTX_new();
    int32_t                 curve           = -1;
    int32_t                 peerKeySize     = -1;

    // One way of setting up EC key
    EC_GROUP                *ecGroup        = NULL;
    point_conversion_form_t form            = POINT_CONVERSION_UNCOMPRESSED;
    int32_t                 asn1_flag       = OPENSSL_EC_NAMED_CURVE;

    // Initialize output so that a return will result to NULL key and zero
    // length if error condition.
    *secretLen = 0;
    secretKey = NULL;

    // Create EC priv Key
    switch(privKeySize)
    {
        case 32:
            curve = NID_X9_62_prime256v1;
            break;
        case 48:
            curve = NID_secp384r1;
            break;
        case 66:
            curve = NID_secp521r1;
            break;
        default:
            return;
    }
    peerKeySize = (2 * privKeySize + 1); // Add one for compression byte

    try {
        if(NULL == (ecGroup = EC_GROUP_new_by_curve_name(curve))) {throw ossl_error();}
        EC_GROUP_set_asn1_flag(ecGroup, asn1_flag);
        EC_GROUP_set_point_conversion_form(ecGroup, form);
        if(NULL == (ecPrivKey = EC_KEY_new())) {throw ossl_error();}
        if(NULL == (ecPeerKey = EC_KEY_new())) {throw ossl_error();}
        if(1 != (EC_KEY_set_group(ecPrivKey, ecGroup))) {throw ossl_error();}
        if(1 != (EC_KEY_set_group(ecPeerKey, ecGroup))) {throw ossl_error();}

        /* PRIVATE KEY SETUP */
        // Convert to BIGNUM for private key conversion
        if(NULL == (BN_bin2bn(pKey, (privKeySize * 8), privBN))) {throw ossl_error();}

        // Convert private key to EC_KEY
        if(1 != (EC_KEY_set_private_key(ecPrivKey, privBN))) {throw ossl_error();}

        // Set the public key from the private key
        if(NULL == (ecPubKey = EC_POINT_new(EC_KEY_get0_group(ecPrivKey)))) {throw ossl_error();}
        if(1 != (EC_POINT_mul(EC_KEY_get0_group(ecPrivKey), ecPubKey,
                EC_KEY_get0_private_key(ecPrivKey), NULL, NULL, NULL))) {throw ossl_error();}
        if(1 != (EC_KEY_set_public_key(ecPrivKey, ecPubKey))) {throw ossl_error();}

        // Set the key in EVP_PKEY to ecPrivKey
        evpPrivKey = EVP_PKEY_new();
        if(1 != (EVP_PKEY_set1_EC_KEY(evpPrivKey, ecPrivKey))) {throw ossl_error();}

        /* PUBLIC PEER KEY SETUP */
        if(NULL == (point = EC_POINT_new(EC_KEY_get0_group(ecPeerKey)))) {throw ossl_error();}
        if(1 != (EC_POINT_oct2point(EC_KEY_get0_group(ecPeerKey), point, peerKey,
                peerKeySize, ctx))) {throw ossl_error();}

        if(1 != (EC_KEY_set_public_key(ecPeerKey, point))) {throw ossl_error();}

        // Set the key in EVP_PKEY to ecPeerKey
        if(1 != (EVP_PKEY_set1_EC_KEY(evpPeerKey, ecPeerKey))) {throw ossl_error();}

        /* SHARED SECRET SETUP */
        if(NULL == (sharedCtx = EVP_PKEY_CTX_new(evpPrivKey, NULL))) {throw ossl_error();}

        // Initialize
        if(1 != (EVP_PKEY_derive_init(sharedCtx))) {throw ossl_error();}

        // Provide the peer (public) key
        if(1 != (EVP_PKEY_derive_set_peer(sharedCtx, evpPeerKey))){throw ossl_error();}

        // Determine the buffer length for shared secret
        if((1 != EVP_PKEY_derive(sharedCtx, NULL, secretLen))) {throw ossl_error();}

        // Generate the shared secret buffer
        if(NULL == (secretKey = reinterpret_cast<unsigned char *>(OPENSSL_malloc(*secretLen))))
                {throw ossl_error();}

        // Derive the shared secret
        if(1 != (EVP_PKEY_derive(sharedCtx, secretKey, secretLen))) {throw ossl_error();}
    } catch(ossl_error& ex) {
        *secretLen = 0;
        secretKey = NULL;

        if(NULL != ecPrivKey) { EC_KEY_free(ecPrivKey); }
        if(NULL != ecPeerKey) { EC_KEY_free(ecPeerKey); }
        if(NULL != ecPubKey) { EC_POINT_free(ecPubKey); }
        if(NULL != point) { EC_POINT_free(point); }
        if(NULL != sharedCtx) { EVP_PKEY_CTX_free(sharedCtx); }
        if(NULL != evpPrivKey) { EVP_PKEY_free(evpPrivKey); }
        if(NULL != evpPeerKey) { EVP_PKEY_free(evpPeerKey); }
        if(NULL != ctx) { BN_CTX_free(ctx); }
        if(NULL != privBN) { BN_free(privBN); }

        return;
    }
    EC_KEY_free(ecPrivKey);
    EC_KEY_free(ecPeerKey);
    EC_POINT_free(ecPubKey);
    EC_POINT_free(point);
    EVP_PKEY_CTX_free(sharedCtx);
    EVP_PKEY_free(evpPrivKey);
    EVP_PKEY_free(evpPeerKey);
    BN_CTX_free(ctx);
    BN_free(privBN);

}

int main ()
{
    int32_t         keySizeBits     = 384;
    int32_t         keySize         = keySizeBits / 8;
    unsigned char   privateKeyData[keySize];
    unsigned char   publicKeyData[keySize * 2 + 1];
    unsigned char   keyIdData[keySize];
    unsigned char   privateKeyData2[keySize];
    unsigned char   publicKeyData2[keySize * 2 + 1];
    unsigned char   keyIdData2[keySize];
    unsigned char* sharedSecret = new unsigned char[keySize];
    unsigned char* sharedSecret2 = new unsigned char[keySize];
    size_t          secretLen       = 0;
    size_t          secretLen2      = 0;

    unsigned char _privateKeyData[] = {
            0x5d, 0xf0, 0x0d, 0x0f, 0x47, 0x1b, 0x3c, 0x11, 0xb7, 0x5d,
            0x12, 0x90, 0xff, 0x91, 0x93, 0xe6, 0xba, 0xd0, 0x75, 0xf9,
            0xe3, 0x48, 0xa2, 0x09, 0x85, 0x05, 0xe1, 0x0a, 0xf2, 0xfd,
            0xad, 0x9a, 0xf7, 0x98, 0xa3, 0xb3, 0x5f, 0x23, 0x80, 0xf2,
            0x05, 0x73, 0xeb, 0x73, 0x85, 0x0c, 0x1b, 0x3e
    };

    unsigned char _publicKeyData[] = {
            0x04, 0x9b, 0x6e, 0x53, 0x33, 0x4f, 0x87, 0x18, 0x45, 0xee,
            0x17, 0x9a, 0xbe, 0xa6, 0x41, 0xe1, 0xf0, 0xb2, 0x52, 0x9f,
            0xe5, 0x22, 0x67, 0x80, 0x64, 0x3b, 0x1b, 0x34, 0x8e, 0xa5,
            0x01, 0x2a, 0x06, 0xe4, 0xaa, 0xd2, 0xea, 0x29, 0x0a, 0xf5,
            0xa0, 0x80, 0x49, 0x1f, 0xa9, 0x4a, 0x30, 0x91, 0xd7, 0x59,
            0x27, 0x9c, 0xa8, 0x9b, 0x18, 0x76, 0xe4, 0xd6, 0x27, 0x93,
            0x0a, 0x6f, 0x01, 0x4d, 0x7d, 0x72, 0xb5, 0x78, 0x91, 0x8f,
            0x30, 0x9b, 0xe2, 0x55, 0x3f, 0xfa, 0x13, 0x3c, 0x52, 0x1b,
            0x5f, 0x56, 0xf7, 0x24, 0x3b, 0x54, 0x19, 0x0b, 0x61, 0x28,
            0x54, 0x72, 0x04, 0xd5, 0xb8, 0x0a, 0x76
    };


    unsigned char _privateKeyData2[] = {
            0x50, 0x96, 0xce, 0x89, 0xb3, 0x17, 0xbf, 0x63, 0x3d, 0x05,
            0x95, 0x82, 0x99, 0xc5, 0xd1, 0x75, 0x0d, 0x21, 0x23, 0x38,
            0xd6, 0x5e, 0x2a, 0xc6, 0x11, 0x09, 0xb4, 0xb0, 0x07, 0x18,
            0x0d, 0xa4, 0xb5, 0x2c, 0xf3, 0x96, 0x0d, 0x9c, 0x6e, 0xad,
            0x7c, 0x14, 0x7f, 0x5b, 0xcd, 0xfd, 0x33, 0xce
    };


    unsigned char _publicKeyData2[] = {
            0x04, 0x29, 0x00, 0x8a, 0xe7, 0xe2, 0x81, 0xab, 0xf2, 0xf4,
            0x2e, 0x1b, 0xb3, 0x73, 0xb4, 0xfd, 0xc6, 0x7e, 0x5e, 0x02,
            0x61, 0x25, 0x65, 0x6d, 0x5e, 0x44, 0xc9, 0x66, 0x21, 0x83,
            0x10, 0xea, 0xdc, 0x36, 0xa9, 0x7d, 0x1a, 0x55, 0xf0, 0x27,
            0xa5, 0x6f, 0x71, 0x36, 0x70, 0x57, 0xf7, 0x9f, 0x3b, 0x58,
            0x78, 0x3a, 0x14, 0x42, 0x58, 0x13, 0xf6, 0xef, 0xcb, 0x55,
            0xe2, 0xaa, 0x50, 0x95, 0x20, 0xa7, 0x29, 0x9c, 0x78, 0x94,
            0x9e, 0xe8, 0x81, 0x5a, 0x8e, 0x6e, 0x45, 0xd8, 0xd1, 0xae,
            0x1b, 0x51, 0x80, 0xcf, 0xce, 0x0c, 0x06, 0xab, 0x7d, 0xca,
            0xa3, 0xff, 0x4e, 0x65, 0x97, 0xb8, 0xd6
    };

    memset(privateKeyData, 0, keySize);
    memset(publicKeyData, 0, keySize * 2 + 1);
    memset(privateKeyData2, 0, keySize);
    memset(publicKeyData2, 0, keySize * 2 + 1);
    memset(sharedSecret, 0, keySize);
    memset(sharedSecret2, 0, keySize);
    memcpy(privateKeyData, _privateKeyData, keySize);
    memcpy(publicKeyData, _publicKeyData, keySize * 2 + 1);
    memcpy(privateKeyData2, _privateKeyData2, keySize);
    memcpy(publicKeyData2, _publicKeyData2, keySize * 2 + 1);

    deriveSharedSecret(privateKeyData, publicKeyData2,
            reinterpret_cast<unsigned char * &>(sharedSecret), &secretLen, keySizeBits / 8);
    deriveSharedSecret(privateKeyData2, publicKeyData,
            reinterpret_cast<unsigned char * &>(sharedSecret2), &secretLen2, keySizeBits / 8);

    OPENSSL_free(sharedSecret);
    OPENSSL_free(sharedSecret2);

    cout << "Out of Main" << endl;

    return 0;
}
int32\u t生成对称密钥对(
int32_t keySizeBits,
无符号字符*publicKeyData,
未签名字符*privateKeyData,
无符号字符*keyIdData)
{
EC_KEY*ecKey=EC_KEY_new();
EC_点*ecPoint=NULL;
常数EC_点*ecPoint2=NULL;
ECU组*ecGroup=NULL;
点转换形式=点转换未压缩;
int32_t asn1_flag=OPENSSL_EC_命名_曲线;
int32_t SizePvKeyBytes=0;
int32_t sizePubKeyBytes=0;
开关(按键开关)
{
案例256:
ecGroup=EC_GROUP_new_by_curve_name(对象sn2nid(“prime256v1”);
打破
案例384:
ecGroup=EC_GROUP_new_by_curve_name(OBJ_sn2nid(“secp384r1”);
打破
案例521:
ecGroup=EC_GROUP_new_by_curve_name(OBJ_sn2nid(“secp521r1”);
打破
违约:
返回0;
}
SizePvKeyBytes=keySizeBits/8+((keySizeBits%8)>0)?1:0;
sizePubKeyBytes=SizePvKeyBytes*2+1;
EC_组_设置_asn1_标志(ecGroup,asn1_标志);
EC组\集合\点\转换\表格(ecGroup,表格);
ECU密钥组(ecKey,ecGroup);
ecPoint=EC_点_新(ecGroup);
if(ECU密钥生成密钥(ecKey))
{
常量BIGNUM*bn;
/*获取私钥*/
bn=EC_密钥\u get0_私钥(ecKey);
bn2bin(BN,privateKeyData);
/*获取公钥*/
ecPoint2=EC_密钥\u get0_公钥(ecKey);
ECU点ECU点2CT(ECU键get0键组(ecKey),
ecPoint2,
点\转换\未压缩,
publicKeyData,
sizePubKeyBytes,
无效);
/*计算密钥ID,忽略格式字节[0]*/
SHA1(publicKeyData+1,sizePubKeyBytes-1,keyIdData);
}
其他的
{
返回0;
}
返回1;
}
无效派生共享秘密(
未签名字符*pKey,
未签名字符*peerKey,
未签名字符*&secretKey,
尺寸*secretLen,
int32_t privKeySize)
{
bool grpForEc=真;
EVP_PKEY_CTX*sharedCtx;
EC_KEY*ecPrivKey=NULL;
EC_KEY*ecPeerKey=NULL;
EVP_PKEY*evpPrivKey=EVP_PKEY_new();
EVP_PKEY*evpPeerKey=EVP_PKEY_new();
BIGNUM*privBN=BN_new();
EC_点*ecPubKey=NULL;
EC_点*点=空;
BN_CTX*CTX=BN_CTX_new();
int32_t曲线=-1;
int32_t peerKeySize=-1;
//一种设置EC密钥的方法
ECU组*ecGroup=NULL;
点转换形式=点转换未压缩;
int32_t asn1_flag=OPENSSL_EC_命名_曲线;
//初始化输出,以便返回NULL键和零
//错误条件下的长度。
*secretLen=0;
secretKey=NULL;
//创建EC私钥
开关(私钥大小)
{
案例32:
曲线=NID_X9_62_prime256v1;
打破
案例48:
曲线=NID_secp384r1;
打破
案例66:
曲线=NID_secp521r1;
打破
违约:
返回;
}
peerKeySize=(2*privKeySize+1);//为压缩字节添加一个
试一试{
如果(NULL==(ecGroup=EC_GROUP_new_by_curve_name(curve)){throw ossl_error();}
EC_组_设置_asn1_标志(ecGroup,asn1_标志);
EC组\集合\点\转换\表格(ecGroup,表格);
如果(NULL==(ecPrivKey=EC_KEY_new()){throw ossl_error();}
如果(NULL==(ecPeerKey=EC_KEY_new()){throw ossl_error();}
如果(1!=(EC_KEY_set_group(ecPrivKey,ecGroup)){throw ossl_error();}
如果(1!=(EC_KEY_set_group(ecPeerKey,ecGroup)){throw ossl_error();}
/*私钥设置*/
//转换为BIGNUM以进行私钥转换
if(NULL==(BN_bin2bn(pKey,(privKeySize*8),privBN)){throw ossl_error();}
//将私钥转换为EC_密钥
如果(1!=(EC_KEY_set_private_KEY(ecPrivKey,privBN)){throw ossl_error();}
//从私钥设置公钥
如果(NULL==(ecPubKey=EC_POINT_new(EC_KEY_get0_group(ecPrivKey))){throw ossl_error();}
如果(1!=(EC_POINT_mul(EC_KEY_get0_group,ecPrivKey),ecPubKey,
EC_KEY_get0_private_KEY(ecPrivKey),NULL,NULL,NULL)){throw ossl_error();}
如果(1!=(EC_KEY_set_public_KEY(ecPrivKey,ecPubKey)){throw ossl_error();}
//将EVP_PKEY中的钥匙设置为ECPRIVEKEY
E