PKCS5 PBKDF1
Documentation |
#include <cryptopp/pwdbased.h>
|
PKCS5_PBKDF1 is an early key derivation function (KDF) specified by PKCS #5. The function takes a secret seed, usage and iteration count and outputs key material.
PKCS5_PBKDF1
derives from KeyDerivationFunction interface. PKCS5_PBKDF1
provides two DeriveKey
member functions. The first member function is required by KeyDerivationFunction
and accepts a NameValuePairs object to pass arbitrary parameters. The second DeriveKey
overload provides a specialized DeriveKey
with parameters tuned for PKCS5_PBKDF1
.
PKCS5_PBKDF1
is an older standard. Early KDFs from the bygone era include P1363_KDF2
, PKCS12_PBKDF
, PKCS5_PBKDF1
and PKCS5_PBKDF2_HMAC
. New applications should consider using a modern KDF, like HKDF
. HKDF
is state of the art extract-then-expand derivation function with provable security properties.
Constructor
PKCS5_PBKDF1 provides a default constructor.
DeriveKey
unsigned int DeriveKey (byte *derived, size_t derivedLen, byte purpose, const byte *secret, size_t secretLen, const byte *salt, size_t saltLen, unsigned int iterations, double timeInSeconds=0) const
derived
is the buffer to receive the derived key. derivedLen
is the size of the buffer, in bytes.
purpose
is a purpose byte. It is unused for PKCS5_PBKDF1.
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.
iterations
is an iteration count.
timeInSeconds
is the maximum amount of time to iterate the DeriveKey
function.
DeriveKey
returns the number of iteration.
salt
and info
are used to help distinguish one instance or run of the algorithm from another. The parameters can be NULL
.
If timeInSeconds > 0.0
then DeriveKey will run for the specified amount of time. If timeInSeconds
is 0.0
then DeriveKey will run for the specified number of iterations.
KeyDerivationFunction
The base class interface KeyDerivationFunction
member function DeriveKey
calls the overloaded DeriveKey
. The following is from pwdbased.h
.
template <class T> size_t PKCS5_PBKDF1<T>::DeriveKey(byte *derived, size_t derivedLen, const byte *secret, size_t secretLen, const NameValuePairs& params) const { CRYPTOPP_ASSERT(secret /*&& secretLen*/); CRYPTOPP_ASSERT(derived && derivedLen); CRYPTOPP_ASSERT(derivedLen <= MaxDerivedKeyLength()); byte purpose = (byte)params.GetIntValueWithDefault("Purpose", 0); unsigned int iterations = (unsigned int)params.GetIntValueWithDefault("Iterations", 1); double timeInSeconds = 0.0f; (void)params.GetValue("TimeInSeconds", timeInSeconds); ConstByteArrayParameter salt; (void)params.GetValue(Name::Salt(), salt); return DeriveKey(derived, derivedLen, purpose, secret, secretLen, salt.begin(), salt.size(), iterations, timeInSeconds); }
Sample Program
The sample program below demonstrates a PKCS5_PBKDF1 with SHA256.
$ cat test.cxx #include <iostream> #include <string> #include "cryptlib.h" #include "pwdbased.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 derived[SHA256::DIGESTSIZE]; PKCS5_PBKDF1<SHA256> pbkdf; byte unused = 0; pbkdf.DeriveKey(derived, sizeof(derived), unused, password, plen, salt, slen, 1024, 0.0f); 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: E2AF0AABF7C9B53D815876AEEE578F56F43DB6EAB44DFD207E83566C99F58BDD
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 "pwdbased.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 derived[BLAKE2b::DIGESTSIZE]; PKCS5_PBKDF1<BLAKE2b> pbkdf; byte unused = 0; pbkdf.DeriveKey(derived, sizeof(derived), unused, password, plen, salt, slen, 1024, 0.0f); 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: 673986C92ABA410E46057C19F1F92FEFC539701E0516833698ED4EE66B28D8758A09019 CF3D818B1E2E05F8702010BD74929E47157670C0B6304CEB1A88626DD
The sample program below demonstrates a PKCS5_PBKDF1 with SHA256, and uses the derived material to key a block cipher. Notice two different labels are used. First, the label HKDF key derivation to derive the key; and second, the label HKDF iv derivation to derive the initialization vector.
$ cat test.cxx #include <iostream> #include <string> #include "cryptlib.h" #include "pwdbased.h" #include "sha.h" #include "files.h" #include "aes.h" #include "modes.h" #include "hex.h" int main(int argc, char* argv[]) { using namespace CryptoPP; byte password[] ="password"; size_t plen = strlen((const char*)password); byte info1[] = "PKCS5_PBKDF1 key derivation"; size_t ilen1 = strlen((const char*)info1); byte info2[] = "PKCS5_PBKDF1 iv derivation"; size_t ilen2 = strlen((const char*)info2); byte key[AES::DEFAULT_KEYLENGTH]; byte iv[AES::BLOCKSIZE]; PKCS5_PBKDF1<SHA256> pbkdf; byte unused = 0; pbkdf.DeriveKey(key, sizeof(key), unused, password, plen, info1, ilen1, 1024, 0.0f); pbkdf.DeriveKey(iv, sizeof(iv), unused, password, plen, info2, ilen2, 1024, 0.0f); std::cout << "Key: "; StringSource(key, sizeof(key), true, new HexEncoder(new FileSink(std::cout))); std::cout << std::endl; std::cout << "IV: "; StringSource(iv, sizeof(iv), true, new HexEncoder(new FileSink(std::cout))); std::cout << std::endl; CBC_Mode<AES>::Encryption enc; enc.SetKeyWithIV(key, sizeof(key), iv, sizeof(iv)); // Use AES/CBC encryptor return 0; }
Running the program results in the following.
$ ./test.exe Key: C663FC66CB19F02F5F17A3116E7427D6 IV: 7FB9D3B9ADDD8F982DC982516A867D9A
Downloads
No downloads.