Crypt-JWT
view release on metacpan or search on metacpan
# NAME
Crypt::JWT - JSON Web Token (JWT, JWS, JWE) as defined by RFC7519, RFC7515, RFC7516
# SYNOPSIS
# encoding
use Crypt::JWT qw(encode_jwt);
my $jws_token = encode_jwt(payload=>$data, alg=>'HS256', key=>'secret');
my $jwe_token = encode_jwt(payload=>$data, alg=>'PBES2-HS256+A128KW', enc=>'A128GCM', key=>'secret');
# decoding
use Crypt::JWT qw(decode_jwt);
my $data1 = decode_jwt(token=>$jws_token, key=>'secret');
my $data2 = decode_jwt(token=>$jwe_token, key=>'secret');
# DESCRIPTION
Implements **JSON Web Token (JWT)** - [https://tools.ietf.org/html/rfc7519](https://tools.ietf.org/html/rfc7519).
The implementation covers not only **JSON Web Signature (JWS)** - [https://tools.ietf.org/html/rfc7515](https://tools.ietf.org/html/rfc7515),
but also **JSON Web Encryption (JWE)** - [https://tools.ietf.org/html/rfc7516](https://tools.ietf.org/html/rfc7516).
The module implements all algorithms defined in [https://tools.ietf.org/html/rfc7518](https://tools.ietf.org/html/rfc7518) - **JSON Web Algorithms (JWA)**.
This module supports **Compact JWS/JWE** and **Flattened JWS/JWE JSON** serialization. General (multi-recipient) JSON serialization is not supported.
# EXPORT
Nothing is exported by default.
You can export selected functions:
use Crypt::JWT qw(decode_jwt encode_jwt);
Or all of them at once:
use Crypt::JWT ':all';
# FUNCTIONS
## decode\_jwt
my $data = decode_jwt(%named_args);
my ($header, $data) = decode_jwt(%named_args, decode_header=>1);
Returns the decoded payload (in scalar context) or the decoded header
followed by the decoded payload (when `decode_header => 1`). Croaks
on any verification, decryption, or claim-check failure.
Named arguments:
- token
Mandatory. The serialized JWS or JWE token as a string. Both compact
(`.`-separated, 3 segments for JWS / 5 for JWE) and flattened JSON
serialization are accepted.
### JWS compact (3 segments)
$t = "eyJhbGciOiJIUzI1NiJ9.dGVzdA.ujBihtLSr66CEWqN74SpLUkv28lra_CeHnxLmLNp4Jo";
my $data = decode_jwt(token=>$t, key=>$k);
### JWE compact (5 segments)
$t = "eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiQTEyOEtXIn0.UusxEbzhGkORxTRq0xkFKhvzPrXb9smw.VGfOuq0Fxt6TsdqLZUpnxw.JajIQQ.pkKZ7MHS0XjyGmRsqgom6w";
my $data = decode_jwt(token=>$t, key=>$k);
- key
A key used for token decryption (JWE) or token signature validation (JWS).
The value depends on the `alg` token header value.
**Since: 0.038** **SECURITY:** how the `key` argument is shaped matters.
- A bare scalar (e.g. `'secret'`) is always interpreted as a raw octet
string (HMAC secret, AES key, etc.).
- PEM, DER, and JWK-JSON key material **must** be passed as a SCALAR ref
(`\$pem`) or as an appropriate key object - never as a bare string.
- If a public-key string is mistakenly passed as a bare scalar and
`accepted_alg` is not set, an attacker who flips the token's `alg` to
`HS*` can forge a signature using the public-key bytes as the HMAC
secret (the so-called "alg confusion" attack).
- For defense in depth, **always** pin the algorithm with `accepted_alg`.
Overview of supported keys:
JWS alg header key value
------------------ ----------------------------------
none no key required
HS256 string (raw octets) of any length (or perl HASH ref with JWK, kty=>'oct')
HS384 same as HS256
HS512 same as HS256
RS256 public RSA key, perl HASH ref with JWK key structure,
a reference to SCALAR string with PEM or DER or JSON/JWK data,
object: Crypt::PK::RSA, Crypt::OpenSSL::RSA, Crypt::X509 or Crypt::OpenSSL::X509
RS384 public RSA key, see RS256
RS512 public RSA key, see RS256
PS256 public RSA key, see RS256
PS384 public RSA key, see RS256
PS512 public RSA key, see RS256
ES256 public ECC key, perl HASH ref with JWK key structure,
a reference to SCALAR string with PEM or DER or JSON/JWK data,
an instance of Crypt::PK::ECC
ES256K public ECC key, see ES256
ES384 public ECC key, see ES256
ES512 public ECC key, see ES256
EdDSA public Ed25519 key
JWE alg header key value
`0` (default) - do not allow JWS with `none` 'alg' header value
- ignore\_signature
`1` - do not check signature on JWS tokens, **BEWARE: DANGEROUS, INSECURE.**
`0` (default) - check signature on JWS tokens
- accepted\_alg
**Since: 0.038** **SECURITY:** strongly recommended. Pinning `accepted_alg` to
the algorithm (or family) you actually expect prevents "alg confusion"
attacks where a forged token swaps the `alg` header to a different family
\- see the SECURITY note under `key`.
Accepted value types:
- `undef` (default) - accept all `alg` algorithms except `none` (for accepting `none` use `allow_none`)
- Scalar string - the single accepted `alg` name
- ARRAY ref - list of accepted `alg` names
- `Regexp` - the `alg` value must match this regexp
Example:
my $payload = decode_jwt(token=>$t, key=>$k, accepted_alg=>'HS256');
my $payload = decode_jwt(token=>$t, key=>$k, accepted_alg=>['HS256','HS384']);
my $payload = decode_jwt(token=>$t, key=>$k, accepted_alg=>qr/^HS(256|384|512)$/);
**INCOMPATIBLE CHANGE Since: 0.038** Any other argument type (HASH ref,
CODE ref, GLOB ref, etc.) now croaks at decode time; previously such typos
silently became no-ops on the JWE side.
- accepted\_enc
JWE only. Restricts which content-encryption algorithms are accepted.
Accepted value types (same shape as ["accepted\_alg"](#accepted_alg)):
- `undef` (default) - accept all `enc` algorithms
- Scalar string - the single accepted `enc` name
- ARRAY ref - list of accepted `enc` names
- `Regexp` - the `enc` value must match this regexp
Example:
my $payload = decode_jwt(token=>$t, key=>$k, accepted_enc=>'A192GCM');
my $payload = decode_jwt(token=>$t, key=>$k, accepted_enc=>['A192GCM','A256GCM']);
my $payload = decode_jwt(token=>$t, key=>$k, accepted_enc=>qr/^A(128|192|256)GCM$/);
- decode\_payload
`0` - do not decode payload, return it as a raw string (octets).
`1` - decode payload from JSON string, return it as perl hash ref (or array ref) - decode\_json failure means fatal error (croak).
`undef` (default) - if possible decode payload from JSON string, if decode\_json fails return payload as a raw string (octets).
- decode\_header
`0` (default) - `decode_jwt` returns just the decoded payload (scalar
context).
`1` - `decode_jwt` returns `($header, $payload)`; useful when you need
to inspect the JWT header (e.g. `alg`, `kid`, `typ`).
my $payload = decode_jwt(token=>$t, key=>$k);
my ($header, $payload) = decode_jwt(token=>$t, key=>$k, decode_header=>1);
- verify\_iss
**INCOMPATIBLE CHANGE Since: 0.024** If `verify_iss` is specified and the
`iss` (Issuer) claim is completely missing, verification fails.
`CODE ref` - subroutine (with 'iss' claim value passed as argument) should return `true` otherwise verification fails
`Regexp ref` - 'iss' claim value has to match given regexp otherwise verification fails
`Scalar` - 'iss' claim value has to be equal to given string. **Since: 0.029**
`undef` (default) - do not verify 'iss' claim
- verify\_aud
**INCOMPATIBLE CHANGE Since: 0.024** If `verify_aud` is specified and the
`aud` (Audience) claim is completely missing, verification fails.
`CODE ref` - subroutine (with 'aud' claim value passed as argument) should return `true` otherwise verification fails
`Regexp ref` - 'aud' claim value has to match given regexp otherwise verification fails
`Scalar` - 'aud' claim value has to be equal to given string. **Since: 0.029**
`undef` (default) - do not verify 'aud' claim
**Since: 0.036** The `aud` claim may also be an array of strings. The
check succeeds if at least one array element matches; the configured check
(CODE, Regexp, Scalar) is applied individually to each element.
- verify\_sub
**INCOMPATIBLE CHANGE Since: 0.024** If `verify_sub` is specified and the
`sub` (Subject) claim is completely missing, verification fails.
`CODE ref` - subroutine (with 'sub' claim value passed as argument) should return `true` otherwise verification fails
`Regexp ref` - 'sub' claim value has to match given regexp otherwise verification fails
`Scalar` - 'sub' claim value has to be equal to given string. **Since: 0.029**
`undef` (default) - do not verify 'sub' claim
- verify\_jti
**INCOMPATIBLE CHANGE Since: 0.024** If `verify_jti` is specified and the
`jti` (JWT ID) claim is completely missing, verification fails.
`CODE ref` - subroutine (with 'jti' claim value passed as argument) should return `true` otherwise verification fails
`Regexp ref` - 'jti' claim value has to match given regexp otherwise verification fails
( run in 0.994 second using v1.01-cache-2.11-cpan-c221a9de4ec )