Examples: Key Generation

There are two key generation methods described below for each key type:

EC

The three curve types defined in the JWA RFC 7518 for the EC key type are:

  1. "P-256" (openssl curve secp256r1)
  2. "P-384" (openssl curve secp384r1)
  3. "P-521" (openssl curve secp521r1)

Method 1

The basic formula for key generation is openssl ecparam -name CURVE -genkey -noout -out FILE, for example:

openssl ecparam -name secp256r1 -genkey -noout -out ec-secp256r1.pem
openssl ecparam -name secp384r1 -genkey -noout -out ec-secp384r1.pem
openssl ecparam -name secp521r1 -genkey -noout -out ec-secp521r1.pem

The PEM files can then be read using jose_jwk:from_pem_file/1 or JOSE.JWK.from_pem_file/1:

jwk = JOSE.JWK.from_pem_file("ec-secp256r1.pem")

Method 2

The curve names are the same as the ones for OpenSSL.

jwk = JOSE.JWK.generate_key(:secp256r1)
jwk = JOSE.JWK.generate_key(:secp384r1)
jwk = JOSE.JWK.generate_key(:secp521r1)

# Alternative explicit syntax:
jwk = JOSE.JWK.generate_key({:ec, :secp256r1})
jwk = JOSE.JWK.generate_key({:ec, :secp384r1})
jwk = JOSE.JWK.generate_key({:ec, :secp521r1})

Keys may also be generated based on other keys. The new key will use the same curve as the supplied key.

old_jwk = JOSE.JWK.from_pem_file("ec-secp256r1.pem")
new_jwk = JOSE.JWK.generate_key(old_jwk)

oct

This key type is simply an octet or byte sequence (see RFC 7518 Section 6.4).

Method 1

The basic formula for generating a random octet sequence is openssl rand -out FILE BYTE_SIZE, for example:

openssl rand -out oct-128-bit.bin 16

The binary file can then be read using jose_jwk:from_oct_file/1 or JOSE.JWK.from_oct_file/1:

jwk = JOSE.JWK.from_oct_file("oct-128-bit.bin")

Method 2

Calling either of these functions with an integer will generate a random octet sequence.

jwk = JOSE.JWK.generate_key(16)

# Alternative explicit syntax:
jwk = JOSE.JWK.generate_key({:oct, 16})

Keys may also be generated based on other keys. The new key will use the same byte size as the supplied key.

old_jwk = JOSE.JWK.from_oct_file("oct-128-bit.bin")
new_jwk = JOSE.JWK.generate_key(old_jwk)

OKP

This key type is an octet key pair with an associated curve (see draft-ietf-jose-cfrg-curves).

Method 1

NOTE: Only Ed25519 is currently supported by ssh-keygen.

The basic formula for generating a random octet sequence is ssh-keygen -t TYPE -f FILE, for example:

ssh-keygen -t ed25519 -f ed25519

The private key file can then be read using jose_jwk:from_openssh_key_file/1 or JOSE.JWK.from_openssh_key_file/1:

jwk = JOSE.JWK.from_openssh_key_file("ed25519")

Method 2

Calling either of these functions with a specified curve will generate an octet key pair. You may also specify the secret portion of the key after the curve.

% Curve25519
jwk_Ed25519   = JOSE.JWK.generate_key({:okp, :Ed25519})
jwk_Ed25519ph = JOSE.JWK.generate_key({:okp, :Ed25519ph})
jwk_X25519    = JOSE.JWK.generate_key({:okp, :X25519})

% Curve448
% NOTE: Ed448 and Ed448ph are not yet fully supported
jwk_Ed448   = JOSE.JWK.generate_key({:okp, :Ed448})
jwk_Ed448ph = JOSE.JWK.generate_key({:okp, :Ed448ph})
jwk_X448    = JOSE.JWK.generate_key({:okp, :X448})

Keys may also be generated based on other keys. The new key will use the same curve as the supplied key.

old_jwk = JOSE.JWK.from_openssh_key_file("ed25519")
new_jwk = JOSE.JWK.generate_key(old_jwk)

RSA

Both two-prime and multi-prime RSA keys are supported by RFC 7518 Section 6.3, but currently only two-prime RSA keys can be generated by OpenSSL-based generators.

See test/jose_SUITE_data/rsa-multi.pem for an example multi-prime RSA key.

Method 1

The basic formula for generating a RSA key is openssl genrsa -out FILE BIT_SIZE, for example:

openssl genrsa -out rsa-2048.pem 2048

The PEM file can then be read using jose_jwk:from_pem_file/1 or JOSE.JWK.from_pem_file/1:

jwk = JOSE.JWK.from_pem_file("rsa-2048.pem")

Method 2

Note: RSA key generation is dependent on cutkey, which must be included as a dependency. An error will be thrown if cutkey is not found.

The modulus bit size is the only required argument. Optionally, you may specify the public exponent as the second argument (default is 65537).

jwk = JOSE.JWK.generate_key({:rsa, 2048})

# Alternative explicit syntax with public exponent:
jwk = JOSE.JWK.generate_key({:rsa, 4096, 65537})

Keys may also be generated based on other keys. The new key will use the same modulus size and public exponent as the supplied key.

old_jwk = JOSE.JWK.from_pem_file("rsa-2048.pem")
new_jwk = JOSE.JWK.generate_key(old_jwk)