I'm creating HTTP REST service which will be available over tls only.

For authentication purposes I plan to generate JWT token for every user using HMAC HS256. I need a secret key for HMAC.

What are the requirements for secret key?

Do I need a long string of random characters? Or fixed-length string? Or what?

up vote 32 down vote accepted

I've added my answer here as I feel the existing ones don't directly address your question enough for my liking.

Let's look at RFC 4868 (regarding IPSec, however it covers the HMAC-SHA256 function you intend to use - em mine):

Block size: the size of the data block the underlying hash algorithm operates upon. For SHA-256, this is 512 bits, for SHA-384 and SHA-512, this is 1024 bits.

Output length: the size of the hash value produced by the underlying hash algorithm. For SHA-256, this is 256 bits, for SHA-384 this is 384 bits, and for SHA-512, this is 512 bits.

As WhiteWinterWolf notes, longer than B is discouraged because the value must be hashed using SHA-256 first (i.e. 512 bits in this case) and less than L is discouraged (256 bits in this case). However, a 256 bit key is overkill as anything that is 128bits or greater cannot be brute forced in anyone's current lifetime, even if every computer in the world was working on cracking it.

Therefore I'd recommend a 128 bit key, generated with a cryptographically secure pseudo random number generator (CSPRNG). If you want to store this as text then a 128 bit key can be represented by generating a random 32 character length hex string, or alternatively you could generate 16 random bytes and then run them through a base64 function.

  • 1
    Just adding a reference toward the OWASP recommendations regarding session ID length and comments about session ID entropy which provides more explanation about the choice of 128 bits. – WhiteWinterWolf Jan 9 '16 at 10:51
  • 1
    12 bytes, base64 encoded, give 128 bits. Every 6 bits (2^6 = 64) is encoded as an 8-bit char, so we have 12/6*8*8 = 128. – Aryeh Leib Taurog Mar 2 '16 at 14:30
  • 5
    @AryehLeibTaurog: 12 bytes gives a size of 128 bits when base64 encoded, however the underlying entropy would only be 96 bits. This is because not every bit combination is valid in the resultant encoding. – SilverlightFox Mar 2 '16 at 15:38
  • It's inherently dated to estimate the amount of time it takes to brute force anything, even though Moore's law has been slowing down. – Ekevoo Jul 5 '17 at 22:09
  • @eke Not sure what you're referring to as no time was estimated at all in my answer or the following comments. – SilverlightFox Jul 6 '17 at 6:31

The RFC 2104 defining HMAC functions answers this question:

The key for HMAC can be of any length (keys longer than B bytes are first hashed using H). However, less than L bytes is strongly discouraged as it would decrease the security strength of the function. Keys longer than L bytes are acceptable but the extra length would not significantly increase the function strength. (A longer key may be advisable if the randomness of the key is considered weak.)

Keys need to be chosen at random (or using a cryptographically strong pseudo-random generator seeded with a random seed), and periodically refreshed. (Current attacks do not indicate a specific recommended frequency for key changes as these attacks are practically infeasible. However, periodic key refreshment is a fundamental security practice that helps against potential weaknesses of the function and keys, and limits the damage of an exposed key.)

For information, the following notation is used in this excerpt:

We assume H to be a cryptographic hash function where data is hashed by iterating a basic compression function on blocks of data. We denote by B the byte-length of such blocks (B=64 for all the above mentioned examples of hash functions), and by L the byte-length of hash outputs (L=16 for MD5, L=20 for SHA-1).

According to RFC 7518 - JSON Web Algorithms (JWA):

A key of the same size as the hash output (for instance, 256 bits for "HS256") or larger MUST be used with this algorithm. (This requirement is based on Section 5.3.4 (Security Effect of the HMAC Key) of NIST SP 800-117 (sic) [NIST.800-107], which states that the effective security strength is the minimum of the security strength of the key and two times the size of the internal hash value.)

So in the case of JWT, you MUST use a key of at least 256 bits with HS256.

  • This is clearly the right answer. Why isnt it upvoted? – Silver Sep 12 '17 at 8:29

EDIT: Wrong answer. Left undeleted to preserve comments thread.


HMAC user-input keys that are longer than the specific hash algorithms blocksize are first shortened. (By running the long keys through the hash. And then using that hash as the actual key.)

SHA256 outputs 256 bit hashes. That's 32 bytes. So I suggest you generate 256 bit HMAC secret keys. (Using a cryptographically secure random generator.) Keys any longer will offer no additional security.

  • Did I get it correct: I need to generate random 256 bit sequence (in case of using HMAC with HS256) using cryptographically secure random generator and then use it as key? – ivstas Aug 5 '15 at 11:14
  • 1
    If you want HMAC-SHA256's maximum strength, then yes. – StackzOfZtuff Aug 5 '15 at 11:25
  • 6
    Let's be precise: with SHA-256, the output size is 256 bits, but the block size is 512 bits, so the "shortening" occurs only for keys of more than 512 bits. However, cryptographic keys (for symmetric algorithms like HMAC) longer than 128 bits don't really add security, so there is no actual need to go to a full block-length key. – Tom Leek Aug 5 '15 at 12:16
  • 1
    To be even more precise: you would use a random number generator for a completely new key. It is possible for instance to obtain a key from a Key Derivation Function, possibly using a key agreement protocol. As long as all the allowed keys for your specific size are equally possible to an attacker you're good. – Maarten Bodewes Aug 5 '15 at 13:26
  • 1
    Thanks, Tom, Maarten. I've placed a warning above my former answer. I'm leaving it alive for sake of this comments thread. – StackzOfZtuff Aug 5 '15 at 13:36

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.