I'm having an issue with allocating a new key for 3 key Triple DES in crypto++.
I've generated a new key as a string but need to allocate it to SecByteBlock for use in Crypto++.
Currently I generate a random key using the PRNG at the start, but when I attempt to change the key using string output from DES_EDE3, it appears to use the same key.
I think the issue is with the conversion between string and SecByteBlock, or the allocation to SecByteBlock as shown below.
Any help would be greatly appreciated!
SecByteBlock GENERATOR::setKey(string keyString){
SecByteBlock replacementKey(24);
replacementKey= SecByteBlock(reinterpret_cast<const byte*>(keyString.data()), keyString.size());
return newKey = replacementKey;
}
I attempt to change the key using string output from DES_EDE3, it appears to use the same key
It almost sounds like you are trying to use 3-DES as a PRF keyed with a password. If so, use HKDF. Its designed for these types of expand-then extract operations.
HKDF is available in Crypto++ 5.6.3 and above. If you need it for a downlevel client, then copy the header where you need it.
SecByteBlock GENERATOR::setKey(string keyString){
SecByteBlock replacementKey(24);
replacementKey= SecByteBlock(reinterpret_cast<const byte*>(keyString.data()), keyString.size());
return newKey = replacementKey;
}
Though you size replacementKey
to 24, it could be resized by the assignment replacementKey= SecByteBlock(...)
.
You might want to try the following:
SecByteBlock GENERATOR::setKey(const string& keyString)
{
SecByteBlock key((const byte*)keyString.data(), keyString.size());
if(key,size() < DES_EDE3::KEYLENGTH)
key.CleanGrow(DES_EDE3::KEYLENGTH);
else
key.resize(DES_EDE3::KEYLENGTH);
return key;
}
CleanGrow
sizes the memory block to DES_EDE3::KEYLENGTH
and backfills the block with 0's as needed. resize
will truncate to DES_EDE3::KEYLENGTH
if its too large.
You could also do something like:
SecByteBlock key(DES_EDE3::KEYLENGTH);
size_t s = STDMIN(key.size(), keyString.size());
memcpy(key.data(), keyString.data(), s);
if(s < DES_EDE3::KEYLENGTH)
memset(key.data()+s, 0, DES_EDE3::KEYLENGTH-s);
To combine the first two, you might consider this:
SecByteBlock GENERATOR::setKey(const string& keyString)
{
// Block is unintialized
SecByteBlock key(DES_EDE3::KEYLENGTH);
HKDF<SHA256> kdf;
kdf.Derivekey(key.data(), key.size(), (const byte*)keyString.data(), keyString.size(), NULL, 0);
return key;
}
You can output a SecByteBlock
with code like:
SecByteBlock b = GENERATOR::setKey(...);
...
cout << "Derived key: "
ArraySource as(b.data(), b.size(), true, new HexEncoder(new FileSink(cout)));
cout << endl;
The following with encode it using Base64:
ArraySource as(b.data(), b.size(), true, new Base64Encoder(new FileSink(cout)));