JSON Web Key (JWK)

The jwk Module implements the JSON Web Key standard. A JSON Web Key is represented by a JWK object, related utility classes and functions are available in this module too.

Classes

class jwcrypto.jwk.JWK(**kwargs)

Bases: dict

JSON Web Key object

This object represents a Key. It must be instantiated by using the standard defined key/value pairs as arguments of the initialization function.

Creates a new JWK object.

The function arguments must be valid parameters as defined in the ‘IANA JSON Web Key Set Parameters registry’ and specified in the JWKParamsRegistry variable. The ‘kty’ parameter must always be provided and its value must be a valid one as defined by the ‘IANA JSON Web Key Types registry’ and specified in the JWKTypesRegistry variable. The valid key parameters per key type are defined in the JWKValuesRegistry variable.

To generate a new random key call the class method generate() with the appropriate ‘kty’ parameter, and other parameters as needed (key size, public exponents, curve types, etc..)

Valid options per type, when generating new keys:
  • oct: size(int)
  • RSA: public_exponent(int), size(int)
  • EC: crv(str) (one of P-256, P-384, P-521, secp256k1)
  • OKP: crv(str) (one of Ed25519, Ed448, X25519, X448)

Deprecated: Alternatively if the ‘generate’ parameter is provided with a valid key type as value then a new key will be generated according to the defaults or provided key strength options (type specific).

Raises:
export(private_key=True, as_dict=False)

Exports the key in the standard JSON format. Exports the key regardless of type, if private_key is False and the key is_symmetric an exception is raised.

Parameters:private_key(bool) – Whether to export the private key. Defaults to True.
Returns:A portable representation of the key. If as_dict is True then a dictionary is returned. By default a json string
Return type:str or dict
export_private(as_dict=False)

Export the private key in the standard JSON format. It fails for a JWK that has only a public key or is symmetric.

Parameters:as_dict(bool) – If set to True export as python dict not JSON
Returns:A portable representation of a private key. If as_dict is True then a dictionary is returned. By default a json string
Return type:str or dict
export_public(as_dict=False)

Exports the public key in the standard JSON format. It fails if one is not available like when this function is called on a symmetric key.

Parameters:as_dict(bool) – If set to True export as python dict not JSON
Returns:A portable representation of the public key only. If as_dict is True then a dictionary is returned. By default a json string
Return type:str or dict
export_to_pem(private_key=False, password=False)

Exports keys to a data buffer suitable to be stored as a PEM file. Either the public or the private key can be exported to a PEM file. For private keys the PKCS#8 format is used. If a password is provided the best encryption method available as determined by the cryptography module is used to wrap the key.

Parameters:
  • private_key – Whether the private key should be exported. Defaults to False which means the public key is exported by default.
  • password(bytes) – A password for wrapping the private key. Defaults to False which will cause the operation to fail. To avoid encryption the user must explicitly pass None, otherwise the user needs to provide a password in a bytes buffer.
Returns:

A serialized bytes buffer containing a PEM formatted key.

Return type:

bytes

classmethod from_json(key)

Creates a RFC 7517 JWK from the standard JSON format.

Parameters:key – The RFC 7517 representation of a JWK.
Returns:A JWK object that holds the json key.
Return type:JWK
classmethod from_password(password)

Creates a symmetric JWK key from a user password.

Parameters:password – A password in utf8 format.
Returns:a JWK object
Return type:JWK
classmethod from_pem(data, password=None)
Creates a key from PKCS#8 formatted data loaded from a PEM file.
See the function import_from_pem for details.
Parameters:
  • data(bytes) – The data contained in a PEM file.
  • password(bytes) – An optional password to unwrap the key.
Returns:

A JWK object.

Return type:

JWK

get_curve(arg)

Gets the Elliptic Curve associated with the key.

Parameters:

arg – an optional curve name

Raises:
Returns:

An EllipticCurve object

Return type:

EllipticCurve

get_op_key(operation=None, arg=None)

Get the key object associated to the requested operation. For example the public RSA key for the ‘verify’ operation or the private EC key for the ‘decrypt’ operation.

Parameters:
  • operation – The requested operation. The valid set of operations is available in the JWKOperationsRegistry registry.
  • arg – An optional, context specific, argument. For example a curve name.
Raises:
Returns:

A Python Cryptography key object for asymmetric keys or a baseurl64_encoded octet string for symmetric keys

import_from_pem(data, password=None, kid=None)

Imports a key from data loaded from a PEM file. The key may be encrypted with a password. Private keys (PKCS#8 format), public keys, and X509 certificate’s public keys can be imported with this interface.

Parameters:
  • data(bytes) – The data contained in a PEM file.
  • password(bytes) – An optional password to unwrap the key.
setdefault(key, default=None)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

thumbprint(hashalg=<cryptography.hazmat.primitives.hashes.SHA256 object>)

Returns the key thumbprint as specified by RFC 7638.

Parameters:hashalg – A hash function (defaults to SHA256)
Returns:A base64url encoded digest of the key
Return type:str
update([E, ]**F) → None. Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

has_private

Whether this JWK has an asymmetric Private key value.

has_public

Whether this JWK has an asymmetric Public key value.

is_symmetric

Whether this JWK is a symmetric key.

key_curve

The Curve Name.

key_id

The Key ID. Provided by the kid parameter if present, otherwise returns None.

key_type

The Key type

class jwcrypto.jwk.JWKSet(*args, **kwargs)

Bases: dict

A set of JWK objects.

Inherits from the standard ‘dict’ builtin type. Creates a special key ‘keys’ that is of a type derived from ‘set’ The ‘keys’ attribute accepts only jwcrypto.jwk.JWK elements.

export(private_keys=True, as_dict=False)
Exports a RFC 7517 key set.
Exports as json by default, or as dict if requested.
Parameters:
  • private_key(bool) – Whether to export private keys. Defaults to True.
  • as_dict(bool) – Whether to return a dict instead of a JSON object
Returns:

A portable representation of the key set. If as_dict is True then a dictionary is returned. By default a json string

Return type:

str or dict

classmethod from_json(keyset)

Creates a RFC 7517 key set from the standard JSON format.

Parameters:keyset – The RFC 7517 representation of a JOSE key set.
Returns:A JWKSet object.
Return type:JWKSet
get_key(kid)

Gets a key from the set. :param kid: the ‘kid’ key identifier.

Returns:A JWK from the set
Return type:JWK
get_keys(kid)

Gets keys from the set with matching kid. :param kid: the ‘kid’ key identifier.

Returns:a List of keys
Return type:list
import_keyset(keyset)

Imports a RFC 7517 key set using the standard JSON format.

Parameters:keyset – The RFC 7517 representation of a JOSE key set.
setdefault(key, default=None)

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None. Update D from dict/iterable E and F.

If E is present and has a .keys() method, then does: for k in E: D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

Exceptions

class jwcrypto.jwk.InvalidJWKType(value=None)

Bases: jwcrypto.common.JWException

Invalid JWK Type Exception.

This exception is raised when an invalid parameter type is used.

class jwcrypto.jwk.InvalidJWKValue

Bases: jwcrypto.common.JWException

Invalid JWK Value Exception.

This exception is raised when an invalid/unknown value is used in the context of an operation that requires specific values to be used based on the key type or other constraints.

class jwcrypto.jwk.InvalidJWKOperation(operation, values)

Bases: jwcrypto.common.JWException

Invalid JWK Operation Exception.

This exception is raised when an invalid key operation is requested, based on the key type and declared usage constraints.

class jwcrypto.jwk.InvalidJWKUsage(use, value)

Bases: jwcrypto.common.JWException

Invalid JWK usage Exception.

This exception is raised when an invalid key usage is requested, based on the key type and declared usage constraints.

Registries

jwcrypto.jwk.JWKTypesRegistry

Registry of valid Key Types

jwcrypto.jwk.JWKValuesRegistry

Registry of valid key values

jwcrypto.jwk.JWKParamsRegistry

Registry of valid key parameters

jwcrypto.jwk.JWKEllipticCurveRegistry

Registry of allowed Elliptic Curves

jwcrypto.jwk.JWKUseRegistry

Registry of allowed uses

jwcrypto.jwk.JWKOperationsRegistry

Registry of allowed operations

Examples

Create a 256bit symmetric key::
>>> from jwcrypto import jwk
>>> key = jwk.JWK.generate(kty='oct', size=256)
Export the key with::
>>> key.export()    #doctest: +ELLIPSIS
'{"k":"...","kty":"oct"}'
Create a 2048bit RSA key pair::
>>> jwk.JWK.generate(kty='RSA', size=2048) #doctest: +ELLIPSIS
{"kid":"Missing Key ID","thumbprint":"..."}
Create a P-256 EC key pair and export the public key::
>>> key = jwk.JWK.generate(kty='EC', crv='P-256')
>>> key.export(private_key=False)   #doctest: +ELLIPSIS
'{"crv":"P-256","kty":"EC","x":"...","y":"..."}'
Import a P-256 Public Key::
>>> expkey = {"y":"VYlYwBfOTIICojCPfdUjnmkpN-g-lzZKxzjAoFmDRm8",
...           "x":"3mdE0rODWRju6qqU01Kw5oPYdNxBOMisFvJFH1vEu9Q",
...           "crv":"P-256","kty":"EC"}
>>> key = jwk.JWK(**expkey)
Import a Key from a PEM file::
>>> with open("public.pem", "rb") as pemfile:  #doctest: +SKIP
...     key = jwk.JWK.from_pem(pemfile.read())