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