I'm implementing ECDHE using crypto next generation APIs (CNG). I generate public and private keys successfully. For pre-shared key, I use BCryptSecretAgreement API, which returns me the pre-shared key secret handle (BCRYPT_SECRET_HANDLE).
How can I export the pre-shared key as BYTE array from the BCRYPT_SECRET_HANDLE?
Starting with Windows 10, you can call
BCryptDeriveKey()
withBCRYPT_KDF_RAW_SECRET
.The resulting key data is the raw secret.
Note 1: bcrypt.h indicates that this format works for "WINBLUE", which would be Windows 8.1, if I understand correctly, but I received STATUS_NOT_SUPPORTED for the use of this KDF type on both Windows 8.1 and Windows Server 2012 R2. This works, however, on Windows 10.)
Note2: I found the data returned using this KDF type to be little-endian (where everything else in BCrypt is big-endian). So, to use the value in an otherwise big-endian world, you need to byte-flip the data.
Once you got your
BCRYPT_SECRET_HANDLE
, you useBCryptDeriveKey
to obtain the actual symmetric encryption key.After calling
BCryptSecretAgreement
, You need to use theBCryptDeriveKey
function to retrieve the shared secret.This can be done as follows:
For the second parameter, the constant
BCRYPT_KDF_HASH
says to use a hash as the key derivation function. The hash to use can be specified in the third parameter. In this example, the third parameter is NULL, so it uses SHA1 by default.Also, the fourth parameter, which is a pointer to the buffer to receive the key, can be NULL. If so, the key is not copied however the number of bytes that would be copied are written to the address given by the sixth parameter. This allows us to allocate the proper amount of space then call the function again, this time passing in the address of the allocated buffer.