JOSEUtils.JWK (jose_utils v0.4.0) View Source
Convenience functions to work with JWKs
Link to this section Summary
Types
A JSON Web Key in its map form
Functions
Returns the list of supported key derivation algorithm for a given JWK
Returns the key type for an algorithm or nil
for the "none"
and "dir"
algorithms
Returns true
if the key conforms to the key selector specification, false
otherwise
Returns the digest used by a signature algorithm of the key
Returns the list of supported signature algorithms for a given JWK
Returns the public key from a private key
Verifies a JWK
Link to this section Types
Specs
certificate() :: any()
Specs
key_op() :: String.t()
Specs
key_selector() :: [key_selector_opt()]
Specs
key_selector_opt() :: {:alg, JOSEUtils.JWA.sig_alg() | JOSEUtils.JWA.enc_alg() | [JOSEUtils.JWA.sig_alg()] | [JOSEUtils.JWA.enc_alg()]} | {:crv, JOSEUtils.JWA.crv() | [JOSEUtils.JWA.crv()]} | {:enc, JOSEUtils.JWA.enc_enc() | [JOSEUtils.JWA.enc_enc()]} | {:key_ops, key_op() | [key_op()]} | {:kid, kid()} | {:kty, kty() | [kty()]} | {:use, use()}
Specs
kid() :: String.t()
Specs
kty() :: String.t()
Specs
result() :: :ok | {:error, atom()}
Specs
A JSON Web Key in its map form
For instance:
%{
"crv" => "P-256",
"kty" => "EC",
"x" => "6pwDpICQ8JBWdvuLuXeWILAxSEUNB_BBAswikgYKKmY",
"y" => "fEHj1ehsIJ7PP-qon-oONl_J2yZLWpUncNRedZT7xqs"
}
Specs
use() :: String.t()
Link to this section Functions
Specs
enc_algs_supported(t()) :: [JOSEUtils.JWA.enc_alg()]
Returns the list of supported key derivation algorithm for a given JWK
Examples
iex> JOSE.JWK.generate_key({:rsa, 2048}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.enc_algs_supported()
["RSA1_5", "RSA-OAEP", "RSA-OAEP-256"]
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.enc_algs_supported()
["ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"]
iex> JOSE.JWK.generate_key({:oct, 16}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.enc_algs_supported()
["A128KW", "A128GCMKW", "dir", "PBES2-HS256+A128KW", "PBES2-HS384+A192KW", "PBES2-HS512+A256KW"]
iex> JOSE.JWK.generate_key({:oct, 32}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.enc_algs_supported()
["A256KW", "A256GCMKW", "dir", "PBES2-HS256+A128KW", "PBES2-HS384+A192KW", "PBES2-HS512+A256KW"]
iex> JOSE.crypto_fallback(true)
iex> JOSE.JWK.generate_key({:okp, :Ed25519}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.enc_algs_supported()
["ECDH-ES", "ECDH-ES+A128KW", "ECDH-ES+A192KW", "ECDH-ES+A256KW"]
Specs
key_type_for_alg(JOSEUtils.JWA.sig_alg() | JOSEUtils.JWA.enc_alg()) :: kty()
Returns the key type for an algorithm or nil
for the "none"
and "dir"
algorithms
Example
iex> JOSEUtils.JWK.key_type_for_alg("RS512")
"RSA"
iex> JOSEUtils.JWK.key_type_for_alg("ECDH-ES+A128KW")
"EC"
iex> JOSEUtils.JWK.key_type_for_alg("dir")
nil
Specs
match_key_selector?(t(), key_selector()) :: boolean()
Returns true
if the key conforms to the key selector specification, false
otherwise
Examples
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([])
true
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([kid: "abc"])
false
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([kty: "EC"])
true
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([kty: "RSA"])
false
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([use: "sig"])
true
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([use: "enc"])
true
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([key_ops: "a"])
true
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([key_ops: "sign"])
true
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"kid" => "key_id"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([alg: ["ES256", "ES512"]])
true
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> Map.put(:fields, %{"alg" => "ES384"}) |> JOSE.JWK.to_map |> elem(1) |> JOSEUtils.JWK.match_key_selector?([alg: ["ES256", "ES512"]])
false
Specs
Returns the digest used by a signature algorithm of the key
Specs
sig_algs_supported(t()) :: [JOSEUtils.JWA.sig_alg()]
Returns the list of supported signature algorithms for a given JWK
Example
iex> JOSE.JWK.generate_key({:ec, "P-256"}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.sig_algs_supported()
["ES256"]
iex> JOSE.JWK.generate_key({:ec, "P-521"}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.sig_algs_supported()
["ES512"]
iex> JOSE.JWK.generate_key({:oct, 32}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.sig_algs_supported()
["HS256"]
iex> JOSE.JWK.generate_key({:oct, 48}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.sig_algs_supported()
["HS256", "HS384"]
iex> JOSE.JWK.generate_key({:oct, 47}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.sig_algs_supported()
["HS256"]
iex> JOSE.JWK.generate_key({:oct, 64}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.sig_algs_supported()
["HS256", "HS384", "HS512"]
iex> JOSE.JWK.generate_key({:rsa,2048}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.sig_algs_supported()
["RS256", "RS384", "RS512", "PS256", "PS384", "PS512"]
iex> JOSE.crypto_fallback(true)
iex> JOSE.JWK.generate_key({:okp, :Ed25519}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.sig_algs_supported()
["EdDSA"]
Specs
Returns the public key from a private key
For "oct"
symmetrical keys, it returns all fields except the "k"
private secret.
It is recommended to have the "kid"
attribute set in this case, otherwise the key
is indistinguishable from other similar symmetrical keys.
Examples
iex> match?(%{"kty" => "EC", "crv" => "P-521"}, JOSE.JWK.generate_key({:ec, "P-521"}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.to_public())
true
iex> JOSE.JWK.generate_key({:oct, 32}) |> JOSE.JWK.to_map() |> elem(1) |> JOSEUtils.JWK.to_public()
%{"kty" => "oct"}
Specs
Verifies a JWK
It performs the following checks:
- verifies that the
"x5c"
member (if present) against:- the JWK key
- the
"alg"
member - the
"use"
member - the
"key_ops"
member - the
"x5t"
member, if present - the
"x5t#S256"
member, if present - validates the certificate chain
- verifies that the
"use"
and"key_ops"
members are consistent - verifies that the
"key_ops"
operations are related to each other