# Expanding Key Material

Is there a way to take key material (for example 256 random bits for an AES key) and "expand" it over to a larger amount of data? Or can I go the opposite way and take a large amount of random data and Xor it down to 256 bits and use that (this looks like secret-sharing, but I do not know if anything changes because the "participants" would all be in the same place)?

I want to store a key, but I don't want it to be just 256 bits since it makes it hard to destroy it on certain types of media. The "key" should be a very large file such that if any portion of it on the media is damaged, the entire key is unable to be retrieved.

Just to be clear, I do not want to have "extra bits" of security. I just want to be able to have 256 bits (or whatever the algorithm is using) of security over a larger amount of storage to make key recovery on the physical storage media harder.

• See, Key Derivation Functions, here or Wikipedia. Bcrypt, PBKDF2, Argon2. – kelalaka Sep 12 '19 at 17:30
• @kelalaka That almost looks like the opposite of what I'm trying to do ("key stretching"). Are KDFs secure when taking a large input and converting into a small key? – user Sep 12 '19 at 17:38
• Did you see this Maximum password length in PBKDF2. The more input the more entropy. – kelalaka Sep 12 '19 at 17:40
• Key stretching is the first thing that came to mind when I read your post as well. "'expand' it over to a large amount of data" sure sounds like key stretching to me. – Swashbuckler Sep 12 '19 at 20:06
• @ErwanLegrand Correct, I want to have a 256 bits of entropy small key from a large secret. This is so that when I try to destroy the physical media that the secret is on, I do not want it to be recoverable from bits and pieces of it. A tiny 256 bit secret on a disk may be recoverable even if the platters are smashed, whereas a 256 bit secret that is generated from the entire device should not be recoverable if even a small fragment is missing. Similarly trying to wipe an SSD by spraying random data onto it will probably leave the 256 bit key, but overwriting part of a huge secret is easy. – user Sep 13 '19 at 13:19

Yes, you could use the HKDF-expand function to expand the bits of the key to a certain size and then use HKDF-extract to derive a key from it again. Note that the resulting key is not identical to the key you've started with. You can use the HKDF-expand again to derive one or more multiple keys with any size from the extracted key material.

HKDF internally uses a hash function (it's a Hash based Key Derivation Function). So it should be fine as long you use SHA-256 or above for 256 bit of input material. The entropy in the output material should be (close to) 256 bits.

Just like a normal hash, you would need all the input data to calculate the correct output, so if only part of the enlarged key gets known you might be still secure, as long as the amount of unknown material is large enough (so brute force attacks are unlikely to succeed).

You can leave the other arguments to HKDF-extract / expand empty if you don't know what to do with them. Using an empty salt seems fine for this kind of purpose.

• is it a good idea to skip the expand and enter your large data? Also, does HKDF a deterministic process? – kelalaka Sep 13 '19 at 10:59
• I do not understand why you would not use a salt. Generating an encryption key from a high-entropy secret is business as usual for HKDF. Or do you assume only one message will be encrypted? – Erwan Legrand Sep 13 '19 at 11:13
• @ErwanLegrand Generally you'd use an IV for separate messages. You can certainly use a salt to derive different keys from HKDF, but that was simply not asked for, hence I didn't include it. I would strongly suggest not to apply my solution without studying HKDF - of course. – Maarten Bodewes Sep 13 '19 at 21:16

TL;DR Here is how these things are done in practice:

1. Feed entropy to a CSPRNG
2. Use CSPRNG to generate master secret (in your case a very large one)
3. Use master secret to encrypt messages
1. Use CSPRNG to generate "salt"
2. Use HKDF with master secret and salt to generate ephemeral pseudo-random numbers (encryption keys, IVs, MAC keys...)
3. Encrypt and protect message against tempering using the ephemeral numbers generated by the KDF

The only unusual part in your use case is your secret needs to be very big.

There are several types of cryptographic primitives which take a small amount of data as input and provide a larger output without loosing a lot of entropy: CPRNGs, stream ciphers and KDFs do this.

If your key material is initially provided by a CSPRNG, which is most likely the case, the rational answer is to fetch the number of bits that you require directly from the CPRNG. (If you have some "real" entropy, use it to feed your CSPRNG!)

Fetching 256 bits from a CSPRNG, generating a longer bit stream from those 256 bits using another algorithm and throwing away the original 256 bits does not make much sense I would say. Just do without the unneeded complexity.

Note that the output of the CSPRNG, however long, does not contain more entropy that the internal state of the CSPRNG and that generating more pseudo-random bytes does not "consume" entropy.

Regarding the other part of your question, I agree with Maarten Bodewes. Turning a high entropy secret into an encryption key is HKDF's job. This part is a no-brainer.

• I think they're saying no salt is fine because it's taking a large amount of random data and reducing it to a smaller key, so there aren't any issues with it being in precomputed tables. – user Sep 13 '19 at 12:23
• Now, I do not think I understand you either. Rainbow tables are used to crack low entropy secrets (passwords). Salt defeats this. But in the case of encryption salt is also used in KDFs to generate ephemeral secrets from a master secret. In security protocols, encryption keys are usually ephemeral secrets. – Erwan Legrand Sep 13 '19 at 13:09

I want to store a key, but I don't want it to be just 256 bits since it makes it hard to destroy it on certain types of media. The "key" should be a very large file such that if any portion of it on the media is damaged, the entire key is unable to be retrieved.

You're describing an All-or-nothing transform. An AONT lets you encrypt some data and create a ciphertext which can be decrypted by anyone as long as they have the entire ciphertext. If they don't have the entire ciphertext, then they can't figure out the key and can't decrypt any of it at all.

Some other answers recommended using a CSPRNG, hash, or key-derivation function to stretch the key, but all of these are one-way functions. You can't get the original 256-bit key back out of the results of these. With an AONT, you can get back to the original short key. (You could instead forget about the original short key and use the stretched result as a new key, but that may be unwieldy. Or you could use the stretched result as the input into a hash or KDF to generate a new 256-bit key.)

• Nice, never heard of that one before. It doesn't seem to be very popular though, has there been much research into AONT algorithms? – user Sep 16 '19 at 12:32