I'm trying to generate a secret key to be used for HMAC SHA-256 signature processing. I've seen many sample of keys with variable length from 32 characters to 96 characters.
What is the ironclad rule for this key size?
Cryptography Stack Exchange is a question and answer site for software developers, mathematicians and others interested in cryptography. It only takes a minute to sign up.
Sign up to join this communityThe only rule for the key is that it should at least contain 256 bits of randomness. If the key is smaller you may not get the full security of HMAC-SHA-256. The full security of HMAC is basically identical to the output size. Unless you are trying to protect yourself against quantum computers you should be able to get away with a key that contains 128 bits of entropy though.
Here's the text from the HMAC standard captured in RFC 2104:
The authentication key K can be of any length up to B, the block length of the hash function. Applications that use keys longer than B bytes will first hash the key using H and then use the resultant L byte string as the actual key to HMAC. In any case the minimal recommended length for K is L bytes (as the hash output length).
So preferably the entropy of the 256 bit key should be condensed into 32 bytes. What you are talking about is probably the hexadecimal representation of those 32 bytes. If the key is too large it may affect performance and efficiency of the HMAC function. Many libraries only allow binary to be inserted using octets bytes anyway, so in that case it makes sense to hex decode the key before you use it.
HMAC uses a hash internally, which is defined for any bit string. This hash is used both for the key as for the value. So in principle you can feed it anything you want up to the maximum hash size (which you will never reach).
Definition from Wikipedia:
$ {\begin{aligned}\operatorname {HMAC} (K,m)&=\operatorname {H} {\Bigl (}{\bigl (}K'\oplus opad{\bigr )}\parallel \operatorname {H} {\bigl (}\left(K'\oplus ipad\right)\parallel m{\bigr )}{\Bigr )}\\K'&={\begin{cases}\operatorname {H} \left(K\right)&K{\text{ is larger than block size}}\\K&{\text{otherwise}}\end{cases}}\end{aligned}} $
Note the repetition of the key with regards to efficiency.
The concrete answer is B, as defined in RFC 2104
The authentication key K can be of any length up to B, the block length of the hash function. (B=64 for all the above mentioned examples of hash functions)
It is difficult to determine what is meant by "the block length of the hash function", so let's go digging in another RFC for information!
From RFC 4634, Page 18
SHA256_Message_Block_Size = 64
Then a lot further down, on Pages 69-70:
/*
* USHABlockSize
*
* Description:
* This function will return the blocksize for the given SHA
* algorithm.
*
* Parameters:
* whichSha:
* which SHA algorithm to query
*
* Returns:
* block size
*
*/
int USHABlockSize(enum SHAversion whichSha)
{
switch (whichSha) {
case SHA1: return SHA1_Message_Block_Size;
case SHA224: return SHA224_Message_Block_Size;
case SHA256: return SHA256_Message_Block_Size;
case SHA384: return SHA384_Message_Block_Size;
default:
case SHA512: return SHA512_Message_Block_Size;
}
}
Picking anything greater than B will get hashed to L, the output of the hash function H.
B offers more security than L, so pick B.