This article describes how to generate a MAC key for HMAC SHA-256 with sufficient entropy to meet requirements of JSON Web Token / JSON Web Algorithms.

As defined in RFC 7519

JSON Web Token (JWT) is a compact, URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted.

The associated JSON Web Algorithms (JWA) RFC 7518 defines the acceptable signing and encryption algorithms for JWT. Under JWA, all conforming JWT implementations MUST provide support for the HMAC SHA-256 algorithm.

HMAC SHA-256 (HS256)

RFC 4949 defines HMAC as

A keyed hash [R2104] that can be based on any iterated cryptographic hash (e.g., MD5 or SHA-1), so that the cryptographic strength of HMAC depends on the properties of the selected cryptographic hash.

From Wikipedia

In cryptography, a message authentication code (MAC) is a short piece of information used to authenticate a message—in other words, to confirm that the message came from the stated sender (its authenticity) and has not been changed in transit (its integrity).

HMAC SHA-256 is a keyed Hash Message Authentication Code (HMAC) based on the SHA-256 algorithm. The HMAC is used in JWT to form a Json Web Signature (JWS) RFC 7515 to provide message integrity for a JWT token. It should be noted that the RFC only refers to message integrity and NOT message authenticity.

The HMAC SHA-256 MAC is generated by JWT implementations using SHA-256 as the hash algorithm, using the JWS Signing Input as the “text” value, and using a secret key. The HMAC output value is the JWS Signature.

JWA defines the following requirement for key generation for the HS256 agorithm

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 [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.)

Generate Secret Key in Python

We need to be able to generate a secret key of minimum size 256 bits to provide as an input to the HMAC SHA-256 algorithm when generating a JWT token.

The Python Standard Library provides the function os.urandom(n) which according to the documentation > This function returns random bytes from an OS-specific randomness source. The returned data should be unpredictable enough for cryptographic applications, though its exact quality depends on the OS implementation.

So, assuming we are satisfied with our OS implementation, we can simply generate an appropriate key in hex representation.

from os import urandom
from binascii import hexlify

def genKey(numBits):
    randomBytes = urandom(numBits / 8)
    return hexlify(randomBytes)

print genKey(256)

Expanding our example, we can then use the pyjwt library generate a JWT using our secret key.

from os import urandom
from binascii import hexlify
import jwt

def genKey(numBits):
    randomBytes = urandom(numBits / 8)
    return hexlify(randomBytes)

key = genKey(256)
print jwt.encode({'some': 'payload'}, key, algorithm='HS256')