Assume that a server has a random secret key, uses it to generate <id = random(), secret = hmac(id, key)> credential tuples, and hands these <id, secret> tuples out to clients freely (over a secured connection).

Are there any weaknesses in a client using its secret to symmetrically encrypt messages directed at the server?

For example:

1. Server setup

  1. Server is loaded with random secret key

2. Credential given to client

  1. Client requests credential over secure channel
  2. Server generates a random id
  3. Server generates a secret by HMACing id with its key
  4. Server responds (over secure channel) with <id, secret> tuple

3. Client sends message to server

  1. Client creates a message M to send to the server
  2. Client generates M' by symmetrically encrypting M and then MACing with its secret
  3. Client sends <id, M'> tuple to server over unsecure channel

4. Server gets message from client

  1. Server receives <id, M'> tuple over unsecure channel
  2. Server derives secret by HMACing id with its key
  3. Server authenticates and decrypts M' using secret

To me, this provides the benefit of the server not needing to persist IDs or secrets, and is also fast (compared to generating RSA key pairs).

But I'm eager to hear downsides of using HMAC like this to generate secret keys?

I tried Googling this scheme but my Google-fu must not be strong enough (this question and answer seem sort of close, but this isn't "Key Derivation" proper, is it?). There must be a good reason why this isn't more common.

Also, is there a name for this?

1 Answer 1


HMAC is a fine candidate for generating keys like that.

After some digging I found this book, which calls the technique "Algorithmically Generating Symmetric Keys from One Base Secret", and which specifically recommends using HMAC: https://www.safaribooksonline.com/library/view/secure-programming-cookbook/0596003943/ch04s11.html

[To create a key,] mix a base secret and any unique information you have available, passing them through a pseudo-random function (PRF), as discussed in the following section.

They later call the "unique information" the distinguisher. For our purposes this is equivalent to the randomly-generated id.

They go on to list several different options for a PRF, including hash functions:

[...] a one-way hash is often good as a PRF.

They expand a little bit on the idea of using a hash function as a PRF:

[...] you can concatenate a base key with unique data and pass the string through SHA1.

The above quote is similar in principle to the definition of HMAC. Indeed the authors cite HMAC specifically as a candidate:

The easiest way to get a solid solution that will resist potentially practical attacks is to use HMAC in counter mode.

This quote is in the context of generating keys longer than the hash block size. Counter mode just means to append a sequential number to the distinguisher as you generate key data. The purpose of a counter is to keep the HMAC's input unique so that the concatenation of output blocks (for the purpose of generating a long key) isn't simply repeating.

For our purposes, there's no need to use counter mode unless the secret needs to be longer than the hash block size.

In the author's words:

If a [generated] key is compromised, it should be impossible to recover the base secret.

They also mention an additional benefit:

Multiple entities in the system should be able to compute the same derived key if they have the right base secret.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .