Используя OpenSSL, я создал свой личный / открытый ключ Диффи-Хеллмана и пытаюсь получить общий секретный ключ. Но функция EVP_PKEY_derive_set_peer () всегда дает сбой. Ниже приведена функция, которая должна получить ключ. Я основал код от кода, найденного на https://github.com/cfairweather/ec-diffie-hellman-openssl/wiki. Любая помощь будет оценена.
unsigned char* deriveSecretKey(key* k, const char *peerPublicKey, int peerPublicKeyLength, int *sharedSecretLength)
{
unsigned char* sharedSecret;
//We can reconstruct an EVP_PKEY on this side to represent the peer key by parsing their public key we received from them.
//New memory buffer that we can allocate using OpenSSL's method
BUF_MEM *bptr = BUF_MEM_new();
BUF_MEM_grow(bptr, peerPublicKeyLength);
//Create a new BIO method, again, memory
BIO* bp = BIO_new(BIO_s_mem());
memcpy(bptr->data, peerPublicKey, peerPublicKeyLength);
BIO_set_mem_buf(bp, bptr, BIO_NOCLOSE);
k->peerkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
if (k->peerkey == NULL)
{
printf("Peer Key is null.\n");
}
//Memory cleanup from read/copy operation
BIO_free(bp);
BUF_MEM_free(bptr);
//Now, let's derive the shared secret
size_t secret_len = 0;
/* Create the context for the shared secret derivation */
if(NULL == (k->ctx_derive = EVP_PKEY_CTX_new(k->privkey, NULL)))
{
printf("Could not create the context for the shared secret derivation\n");
return NULL;
}
/* Initialise */
if(1 != EVP_PKEY_derive_init(k->ctx_derive))
{
printf("Could not init derivation context\n");
return NULL;
}
/* Provide the peer public key */
// This call fails
if(1 != EVP_PKEY_derive_set_peer(k->ctx_derive, k->peerkey))
{
printf("Could not set the peer key into derivation context\n");
return NULL;
}
/* Determine buffer length for shared secret */
if(1 != EVP_PKEY_derive(k->ctx_derive, NULL, &secret_len))
{
printf("Could not determine buffer length for shared secret\n");
return NULL;
}
/* Create the buffer */
if(NULL == (sharedSecret = (unsigned char*) OPENSSL_malloc(secret_len)))
{
printf("Could not create the sharedSecret buffer\n");
return NULL;
}
/* Dervive the shared secret */
if(1 != (EVP_PKEY_derive(k->ctx_derive, sharedSecret, &secret_len)))
{
printf("Could not dervive the shared secret\n");
return NULL;
}
(*sharedSecretLength) = (int)secret_len;
// Hash the secret
unsigned char key[] = "df2677fbc0ddd3b4e059b82207e7840fbe7fd91a64b68935135b4f42b36899c2";
unsigned char iv[] = "17620daa95f8cd7dfef9af3a516a1970";
int secretLength = encrypt(sharedSecret (*sharedSecretLength),key,iv,sharedSecret);
return sharedSecret;
}
Задача ещё не решена.
Других решений пока нет …