После вызова BCryptSecretAgreement
вам необходимо использовать BCryptDeriveKey
для получения общего секрета.
Это можно сделать следующим образом:
// generates an ECDH shared secret from a public key and a private key
int get_ECDH_key(BCRYPT_KEY_HANDLE pubkey, BCRYPT_KEY_HANDLE privkey, unsigned char **key,
unsigned int *keylen)
{
SECURITY_STATUS sstatus;
BCRYPT_SECRET_HANDLE secret;
int _len;
// creates the shared secret, stored in a BCRYPT_SECRET_HANDLE
sstatus = BCryptSecretAgreement(privkey, pubkey, &secret, 0);
if (!BCRYPT_SUCCESS(sstatus)) {
printf("BCryptSecretAgreement failed with status %d", sstatus);
return 0;
}
// find out how much space is needed before retrieving the shared secret
sstatus = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, NULL, NULL, 0, &_len, 0);
if (!BCRYPT_SUCCESS(sstatus)) {
printf("BCryptDeriveKey failed with status %d", sstatus);
return 0;
}
// allocate space for the shared secret
*key = malloc(_len);
if (*key == NULL) {
perror("malloc failed");
exit(1);
}
// retrieve the shared secret
sstatus = BCryptDeriveKey(secret, BCRYPT_KDF_HASH, NULL, *key, _len,
keylen, 0 );
if (!BCRYPT_SUCCESS(sstatus)) {
printf("BCryptDeriveKey failed with status %d", sstatus);
return 0;
}
return 1;
}
Для второго параметра константа BCRYPT_KDF_HASH
говорит об использовании хэша в качестве функции получения ключа. Хэш для использования может быть указан в третьем параметре. В этом примере третий параметр имеет значение NULL, поэтому по умолчанию используется SHA1.
Также четвертый параметр, который является указателем на буфер для получения ключа, может быть NULL. Если это так, ключ не копируется, однако количество копируемых байтов записывается по адресу, заданному шестым параметром. Это позволяет нам выделить нужное количество места, а затем снова вызвать функцию, на этот раз передав адрес выделенного буфера.
person
dbush
schedule
13.11.2016