# Key derivation from a random seed

The main problem is to use a block cipher to generate a random key.

I would like to generate 256-bits key which can be as random as possible. I generate it in the following way:

1. Pick a plaintext $p_0$ of 64 bits and a 256-bit key $k_0$. ( can be given from keyboard as seed)
2. Implement a cipher which goes from 64-bits to 64-bits.
3. Encrypt $p_0$ with this cipher using $k_0$ to get $c_0$. (Assuming that the cipher is a pseudo-random permutation then $c_0$ is pretty random)
4. Set $p_0 = c_0$ and repeat the process say for 1000 times.
5. At the end use the last 4 encrypted messages of the loop to fill the key $k_0$ and take this as the new key.

Is this method random enough? Maybe there is a problem as I'm using all time to encrypt $k_0$? Which is the best implementation to get a really random key?

• Why not use a standardized, widely accepted, cryptographically secure PRNG? One of the first rules in cryptography is don't roll your own. Use something that is already available, has been analyzed by very smart people, etc. – mikeazo Oct 19 '12 at 17:41
• I would like to use this way to see how random the key derived can be. Its not a new construction is something which is very common if a hash function is used instead of a cipher. – Hashed Oct 21 '12 at 11:54

## 2 Answers

What you are describing is called output feedback mode, a mode of operation for block ciphers to create a stream cipher. You are discarding the first 996 output blocks and are using the following four ones.

In general, your algorithm (as any algorithm) can't produce randomness, just stretch existing randomness in a way which might look more random.

If there are $N$ possible values for $p_0$ and $M$ possible values for $k_0$, we get at most $N·M$ possible different values for the final key – no algorithm can do better, arguably.

If the key $k_0$ is fixed (or known to the attacker), she can just as well as you calculate the whole series and get the result from $p_0$ (or even, if she had only one block of the output, calculate $p_0$ and the other blocks of the output).

The moral: don't try to invent your own scheme.

For deriving a key from another, already high entropy key (e.g. to use different keys for different uses), use a key derivation function. Those are often based on a MAC or a hash function, use the key and a "personalizer" as input, and create another key.

For deriving a key from a password (i.e. a low-entropy key which a human can memorize), we want a slow key derivation function. These take a password and a salt (different for each use, but doesn't need to be secret), do a lot of work(configurably much), and produce a key. Examples are PBKDF2, bcrypt and scrypt.

• In case I would like to use a hash function like say SHA-1 to produce a random 256 bits. SHA-1 has 160 bits digests. Is it ok if I start with a random sentence say "10-39-298*&*^&^90" has it many times and collect that last 256 bits? – Hashed Oct 21 '12 at 11:56
• Have a look at the answers to the question I linked (about slow key derivation functions). Use PBKDF2, bcrypt or scrypt (and preferably use SHA-256 instead of SHA-1). – Paŭlo Ebermann Oct 21 '12 at 15:38

You should be using PBKDF2. It is designed for exactly this purpose. Don't design your own when there exists a standard, well-vetted scheme.

But really, in most cases you should not generate cryptographic keys from a human-entered password or passphrase. Such systems are usually insecure, given how users tend to work in practice. See Try to avoid using passwords as encryption keys.