HKDF

From Crypto++ Wiki
Jump to: navigation, search
HKDF
Documentation
#include <cryptopp/hkdf.h>

HKDF is HMAC-based Extract-and-Expand key derivation function by Krawczyk and Eronen. The Crypto++ implementation is from Cryptographic Extraction and Key Derivation: The HKDF Scheme and HMAC-based Extract-and-Expand Key Derivation Function (HKDF).

HKDF provides the KeyDerivationFunction interface rather than the MessageAuthenticationCode interface. The KDF interface consists of a default constructor and a method DeriveKey which derives a user key form the parameters.

Constructor

HKDF provides a default constructor.

DeriveKey

unsigned int DeriveKey (byte *derived, size_t derivedLen,
                        const byte *secret, size_t secretLen,
                        const byte *salt, size_t saltLen,
                        const byte *info, size_t infoLen) const

derived is the buffer to receive the derived key. derivedLen is the size of the buffer, in bytes.

secret is private information to use during derivation. secretLen is the size of the buffer, in bytes.

salt is possibly public information to use during derivation. saltLen is the size of the buffer, in bytes.

info is additional, possibly public information to use during derivation. infoLen is the size of the buffer, in bytes.

DeriveKey returns the number of bytes returned in the derived buffer.

salt and info are used to help distinguish one instance or run of the algorithm from another. The parameters can be NULL.

Sample Program

The sample program below demonstrates a HKDF with SHA1.

$ cat test.cxx
#include <iostream>
#include <string>

#include "cryptlib.h"
#include "hkdf.h"
#include "blake2.h"
#include "filters.h"
#include "sha.h"
#include "hex.h"

int main(int argc, char* argv[])
{
    using namespace CryptoPP;

    byte password[] ="password";
    size_t plen = strlen((const char*)password);

    byte salt[] = "salt";
    size_t slen = strlen((const char*)salt);

    byte info[] = "HKDF key derivation";
    size_t ilen = strlen((const char*)info);

    byte derived[SHA1::DIGESTSIZE];

    HKDF<SHA1> hkdf;
    hkdf.DeriveKey(derived, sizeof(derived), password, plen, salt, slen, info, ilen);

    std::string result;
    HexEncoder encoder(new StringSink(result));

    encoder.Put(derived, sizeof(derived));
    encoder.MessageEnd();

    std::cout << "Derived: " << result << std::endl;

    return 0;
}

Running the program results in the following.

$ ./test.exe
Derived: 9912F20853DFF1AFA944E9B88CA63C410CBB1938

You can swap-in any hash class that provides a blocksize. The code below uses BLAKE2b as the message digest. The BLAKE2b sample below requires Commit 758939ab2e1b.

$ cat test.cxx
#include <iostream>
#include <string>

#include "cryptlib.h"
#include "hkdf.h"
#include "blake2.h"
#include "filters.h"
#include "blake2.h"
#include "hex.h"

int main(int argc, char* argv[])
{
    using namespace CryptoPP;

    byte password[] ="password";
    size_t plen = strlen((const char*)password);

    byte salt[] = "salt";
    size_t slen = strlen((const char*)salt);

    byte info[] = "HKDF key derivation";
    size_t ilen = strlen((const char*)info);

    byte derived[BLAKE2b::DIGESTSIZE];

    HKDF<BLAKE2b> hkdf;
    hkdf.DeriveKey(derived, sizeof(derived), password, plen, salt, slen, info, ilen);

    std::string result;
    HexEncoder encoder(new StringSink(result));

    encoder.Put(derived, sizeof(derived));
    encoder.MessageEnd();

    std::cout << "Derived: " << result << std::endl;

    return 0;
}

Running the program results in the following.

$ ./test.exe
Derived: 4FF891CB129EC9F2B4CF715897B3FC5A0F58C61EC2CD59D71C635C75810EC04763E8C36
BAC7462D58820734B8B09A4FCB956743CDD6FA6976B26B1A1C00E0786

Downloads

No downloads.