.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.40) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Crypt::JWT 3pm" .TH Crypt::JWT 3pm "2021-03-20" "perl v5.32.1" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Crypt::JWT \- JSON Web Token (JWT, JWS, JWE) as defined by RFC7519, RFC7515, RFC7516 .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 4 \& # encoding \& use Crypt::JWT qw(encode_jwt); \& my $jws_token = encode_jwt(payload=>$data, alg=>\*(AqHS256\*(Aq, key=>\*(Aqsecret\*(Aq); \& my $jwe_token = encode_jwt(payload=>$data, alg=>\*(AqPBES2\-HS256+A128KW\*(Aq, enc=>\*(AqA128GCM\*(Aq, key=>\*(Aqsecret\*(Aq); \& \& # decoding \& use Crypt::JWT qw(decode_jwt); \& my $data1 = decode_jwt(token=>$jws_token, key=>\*(Aqsecret\*(Aq); \& my $data2 = decode_jwt(token=>$jwe_token, key=>\*(Aqsecret\*(Aq); .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" Implements \fB\s-1JSON\s0 Web Token (\s-1JWT\s0)\fR \- . The implementation covers not only \fB\s-1JSON\s0 Web Signature (\s-1JWS\s0)\fR \- , but also \fB\s-1JSON\s0 Web Encryption (\s-1JWE\s0)\fR \- . .PP The module implements \fBall (100%) algorithms\fR defined in \- \fB\s-1JSON\s0 Web Algorithms (\s-1JWA\s0)\fR. .PP This module supports \fBCompact \s-1JWS/JWE\s0\fR and \fBFlattened \s-1JWS/JWE JSON\s0\fR serialization, general \s-1JSON\s0 serialization is not supported yet. .SH "EXPORT" .IX Header "EXPORT" Nothing is exported by default. .PP You can export selected functions: .PP .Vb 1 \& use Crypt::JWT qw(decode_jwt encode_jwt); .Ve .PP Or all of them at once: .PP .Vb 1 \& use Crypt::JWT \*(Aq:all\*(Aq; .Ve .SH "FUNCTIONS" .IX Header "FUNCTIONS" .SS "decode_jwt" .IX Subsection "decode_jwt" .Vb 1 \& my $data = decode_jwt(%named_args); .Ve .PP Named arguments: .IP "token" 4 .IX Item "token" Mandatory argument, a string with either \s-1JWS\s0 or \s-1JWE JSON\s0 Web Token. .Sp .Vb 3 \& ### JWS token example (3 segments) \& $t = "eyJhbGciOiJIUzI1NiJ9.dGVzdA.ujBihtLSr66CEWqN74SpLUkv28lra_CeHnxLmLNp4Jo"; \& my $data = decode_jwt(token=>$t, key=>$k); \& \& ### JWE token example (5 segments) \& $t = "eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiQTEyOEtXIn0.UusxEbzhGkORxTRq0xkFKhvzPrXb9smw.VGfOuq0Fxt6TsdqLZUpnxw.JajIQQ.pkKZ7MHS0XjyGmRsqgom6w"; \& my $data = decode_jwt(token=>$t, key=>$k); .Ve .IP "key" 4 .IX Item "key" A key used for token decryption (\s-1JWE\s0) or token signature validation (\s-1JWS\s0). The value depends on the \f(CW\*(C`alg\*(C'\fR token header value. .Sp .Vb 10 \& JWS alg header key value \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& none no key required \& HS256 string (raw octects) of any length (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& HS384 dtto \& HS512 dtto \& 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 \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& dir string (raw octects) or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq, length depends on \*(Aqenc\*(Aq algorithm \& A128KW string (raw octects) 16 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A192KW string (raw octects) 24 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A256KW string (raw octects) 32 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A128GCMKW string (raw octects) 16 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A192GCMKW string (raw octects) 24 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A256GCMKW string (raw octects) 32 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& PBES2\-HS256+A128KW string (raw octects) of any length (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& PBES2\-HS384+A192KW string (raw octects) of any length (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& PBES2\-HS512+A256KW string (raw octects) of any length (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& RSA\-OAEP private RSA 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::RSA or Crypt::OpenSSL::RSA \& RSA\-OAEP\-256 private RSA key, see RSA\-OAEP \& RSA1_5 private RSA key, see RSA\-OAEP \& ECDH\-ES private ECC or X25519 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 \& ECDH\-ES+A128KW private ECC or X25519 key, see ECDH\-ES \& ECDH\-ES+A192KW private ECC or X25519 key, see ECDH\-ES \& ECDH\-ES+A256KW private ECC or X25519 key, see ECDH\-ES .Ve .Sp Example using the key from \f(CW\*(C`jwk\*(C'\fR token header: .Sp .Vb 2 \& my $data = decode_jwt(token=>$t, key_from_jwk_header=>1); \& my ($header, $data) = decode_jwt(token=>$t, decode_header=>1, key_from_jwk_header=>1); .Ve .Sp Examples with raw octet keys: .Sp .Vb 6 \& #string \& my $data = decode_jwt(token=>$t, key=>\*(Aqsecretkey\*(Aq); \& #binary key \& my $data = decode_jwt(token=>$t, key=>pack("H*", "788A6E38F36B7596EF6A669E94")); \& #perl HASH ref with JWK structure (key type \*(Aqoct\*(Aq) \& my $data = decode_jwt(token=>$t, key=>{kty=>\*(Aqoct\*(Aq, k=>"GawgguFyGrWKav7AX4VKUg"}); .Ve .Sp Examples with \s-1RSA\s0 keys: .Sp .Vb 9 \& my $pem_key_string = <<\*(AqEOF\*(Aq; \& \-\-\-\-\-BEGIN PRIVATE KEY\-\-\-\-\- \& MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCoVm/Sl5r+Ofky \& jioRSZK26GW6WyjyfWKddsSi13/NOtCn0rRErSF/u3QrgGMpWFqKohqbi1VVC+SZ \& ... \& 8c1vm2YFafgdkSk9Qd1oU2Fv1aOQy4VovOFzJ3CcR+2r7cbRfcpLGnintHtp9yek \& 02p+d5g4OChfFNDhDtnIqjvY \& \-\-\-\-\-END PRIVATE KEY\-\-\-\-\- \& EOF \& \& my $jwk_key_json_string = \*(Aq{"kty":"RSA","n":"0vx7agoebG...L6tSoc_BJECP","e":"AQAB"}\*(Aq; \& \& #a reference to SCALAR string with PEM or DER or JSON/JWK data, \& my $data = decode_jwt(token=>$t, key=>\e$pem_key_string); \& my $data = decode_jwt(token=>$t, key=>\e$der_key_string); \& my $data = decode_jwt(token=>$t, key=>\e$jwk_key_json_string); \& \& #instance of Crypt::PK::RSA \& my $data = decode_jwt(token=>$t, key=>Crypt::PK::RSA\->new(\*(Aqkeyfile.pem\*(Aq)); \& my $data = decode_jwt(token=>$t, key=>Crypt::PK::RSA\->new(\e$pem_key_string)); \& \& #instance of Crypt::OpenSSL::RSA \& my $data = decode_jwt(token=>$t, key=>Crypt::OpenSSL::RSA\->new_private_key($pem_key_string)); \& \& #instance of Crypt::X509 (public key only) \& my $data = decode_jwt(token=>$t, key=>Crypt::X509\->new(cert=>$cert)); \& \& #instance of Crypt::OpenSSL::X509 (public key only) \& my $data = decode_jwt(token=>$t, key=>Crypt::OpenSSL::X509\->new_from_file(\*(Aqcert.pem\*(Aq)); \& my $data = decode_jwt(token=>$t, key=>Crypt::OpenSSL::X509\->new_from_string($cert)); \& \& #perl HASH ref with JWK structure (key type \*(AqRSA\*(Aq) \& my $rsa_priv = { \& kty => "RSA", \& n => "0vx7agoebGcQSuuPiLJXZpt...eZu0fM4lFd2NcRwr3XPksINHaQ\-G_xBniIqbw0Ls1jF44\-csFCur\-kEgU8awapJzKnqDKgw", \& e => "AQAB", \& d => "X4cTteJY_gn4FYPsXB8rdXi...FLN5EEaG6RoVH\-HLKD9Mdx5ooGURknhnrRwUkC7h5fJLMWbFAKLWY2v7B6NqSzUvx0_YSf", \& p => "83i\-7IvMGXoMXCskv73TKr8...Z27zvoj6pbUQyLPBQxtPnwD20\-60eTmD2ujMt5PoMrm8RmNhVWtjjMmMjOpSicFHjXOuVI", \& q => "3dfOR9cuYq\-0S\-mkFLzgItg...q3hWeMuG0ouqnb3obLyuqjVZQ1dIrdgTnCdYzBcOW5r37AFXjift_NGiovonzhKpoVVS78", \& dp => "G4sPXkc6Ya9y8oJW9_ILj4...zi_H7TkS8x5SdX3oE0oiYwxIiemTAu0UOa5pgFGyJ4c8t2VF40XRugKTP8akhFo5tA77Qe", \& dq => "s9lAH9fggBsoFR8Oac2R_E...T2kGOhvIllTE1efA6huUvMfBcpn8lqW6vzzYY5SSF7pMd_agI3G8IbpBUb0JiraRNUfLhc", \& qi => "GyM_p6JrXySiz1toFgKbWV...4ypu9bMWx3QJBfm0FoYzUIZEVEcOqwmRN81oDAaaBk0KWGDjJHDdDmFW3AN7I\-pux_mHZG", \& }; \& my $data = decode_jwt(token=>$t, key=>$rsa_priv}); .Ve .Sp Examples with \s-1ECC\s0 keys: .Sp .Vb 7 \& my $pem_key_string = <<\*(AqEOF\*(Aq; \& \-\-\-\-\-BEGIN EC PRIVATE KEY\-\-\-\-\- \& MHcCAQEEIBG1c3z52T8XwMsahGVdOZWgKCQJfv+l7djuJjgetdbDoAoGCCqGSM49 \& AwEHoUQDQgAEoBUyo8CQAFPeYPvv78ylh5MwFZjTCLQeb042TjiMJxG+9DLFmRSM \& lBQ9T/RsLLc+PmpB1+7yPAR+oR5gZn3kJQ== \& \-\-\-\-\-END EC PRIVATE KEY\-\-\-\-\- \& EOF \& \& my $jwk_key_json_string = \*(Aq{"kty":"EC","crv":"P\-256","x":"MKB..7D4","y":"4Et..FyM"}\*(Aq; \& \& #a reference to SCALAR string with PEM or DER or JSON/JWK data, \& my $data = decode_jwt(token=>$t, key=>\e$pem_key_string); \& my $data = decode_jwt(token=>$t, key=>\e$der_key_string); \& my $data = decode_jwt(token=>$t, key=>\e$jwk_key_json_string); \& \& #instance of Crypt::PK::ECC \& my $data = decode_jwt(token=>$t, key=>Crypt::PK::ECC\->new(\*(Aqkeyfile.pem\*(Aq)); \& my $data = decode_jwt(token=>$t, key=>Crypt::PK::ECC\->new(\e$pem_key_string)); \& \& #perl HASH ref with JWK structure (key type \*(AqEC\*(Aq) \& my $ecc_priv = { \& kty => "EC", \& crv => "P\-256", \& x => "MKBCTNIcKUSDii11ySs3526iDZ8AiTo7Tu6KPAqv7D4", \& y => "4Etl6SRW2YiLUrN5vfvVHuhp7x8PxltmWWlbbM4IFyM", \& d => "870MB6gfuTJ4HtUnUvYMyJpr5eUZNP4Bk43bVdj3eAE", \& }; \& my $data = decode_jwt(token=>$t, key=>$ecc_priv}); .Ve .IP "keypass" 4 .IX Item "keypass" When 'key' parameter is an encrypted private \s-1RSA\s0 or \s-1ECC\s0 key this optional parameter may contain a password for private key decryption. .IP "kid_keys" 4 .IX Item "kid_keys" This parametes can be either a \s-1JWK\s0 Set \s-1JSON\s0 string (see \s-1RFC7517\s0) or a perl \s-1HASH\s0 ref with \s-1JWK\s0 Set structure like this: .Sp .Vb 7 \& my $keylist = { \& keys => [ \& { kid=>"key1", kty=>"oct", k=>"GawgguFyGrWKav7AX4VKUg" }, \& { kid=>"key2", kty=>"oct", k=>"ulxLGy4XqhbpkR5ObGh1gX" }, \& ] \& }; \& my $payload = decode_jwt(token=>$t, kid_keys=>$keylist); .Ve .Sp The structure described above is used e.g. by .Sp .Vb 4 \& use Mojo::UserAgent; \& my $ua = Mojo::UserAgent\->new; \& my $google_keys => $ua\->get(\*(Aqhttps://www.googleapis.com/oauth2/v2/certs\*(Aq)\->result\->json; \& my $payload = decode_jwt(token => $t, kid_keys => $google_keys); .Ve .Sp \&\fB\s-1SINCE 0.019\s0\fR we also support alternative structure used e.g. by : .Sp .Vb 3 \& use LWP::Simple; \& my $google_certs = get(\*(Aqhttps://www.googleapis.com/oauth2/v1/certs\*(Aq); \& my $payload = decode_jwt(token => $t, kid_keys => $google_certs); .Ve .Sp When the token header contains \f(CW\*(C`kid\*(C'\fR item the corresponding key is looked up in \f(CW\*(C`kid_keys\*(C'\fR list and used for token decoding (you do not need to pass the explicit key via \f(CW\*(C`key\*(C'\fR parameter). .Sp \&\fB\s-1INCOMPATIBLE CHANGE\s0 in 0.023:\fR When \f(CW\*(C`kid_keys\*(C'\fR is specified it croaks if token header does not contain \f(CW\*(C`kid\*(C'\fR value or if \f(CW\*(C`kid\*(C'\fR was not found in \f(CW\*(C`kid_keys\*(C'\fR. .IP "key_from_jwk_header" 4 .IX Item "key_from_jwk_header" \&\fB\s-1SINCE 0.023\s0\fR .Sp \&\f(CW1\fR \- use \f(CW\*(C`jwk\*(C'\fR header value for validating \s-1JWS\s0 signature if neither \f(CW\*(C`key\*(C'\fR nor \f(CW\*(C`kid_keys\*(C'\fR specified, \fB\s-1BEWARE: DANGEROUS, UNSECURE\s0!!!\fR .Sp \&\f(CW0\fR (default) \- ignore \f(CW\*(C`jwk\*(C'\fR header value when validating \s-1JWS\s0 signature .Sp Keep in mind that enabling \f(CW\*(C`key_from_jwk_header\*(C'\fR requires \f(CW\*(C`jwk\*(C'\fR header to exist and be an valid \s-1RSA/ECDSA\s0 public key (otherwise it croaks). .IP "allow_none" 4 .IX Item "allow_none" \&\f(CW1\fR \- accept \s-1JWS\s0 tokens with \f(CW\*(C`none\*(C'\fR 'alg' header value (which means that token has no signature), \fB\s-1BEWARE: DANGEROUS, UNSECURE\s0!!!\fR .Sp \&\f(CW0\fR (default) \- do not allow \s-1JWS\s0 with \f(CW\*(C`none\*(C'\fR 'alg' header value .IP "ignore_signature" 4 .IX Item "ignore_signature" \&\f(CW1\fR \- do not check signature on \s-1JWS\s0 tokens, \fB\s-1BEWARE: DANGEROUS, UNSECURE\s0!!!\fR .Sp \&\f(CW0\fR (default) \- check signature on \s-1JWS\s0 tokens .IP "accepted_alg" 4 .IX Item "accepted_alg" \&\f(CW\*(C`undef\*(C'\fR (default) means accept all 'alg' algorithms except 'none' (for accepting 'none' use \f(CW\*(C`allow_none\*(C'\fR) .Sp \&\f(CW\*(C`string\*(C'\fR name of accepted 'alg' algorithm (only one) .Sp \&\f(CW\*(C`ARRAY ref\*(C'\fR a list of accepted 'alg' algorithms .Sp \&\f(CW\*(C`Regexp\*(C'\fR that has to match 'alg' algorithm name .Sp .Vb 5 \& my $payload = decode_jwt(token=>$t, key=>$k, accepted_alg=>\*(AqHS256\*(Aq); \& #or \& my $payload = decode_jwt(token=>$t, key=>$k, accepted_alg=>[\*(AqHS256\*(Aq,\*(AqHS384\*(Aq]); \& #or \& my $payload = decode_jwt(token=>$t, key=>$k, accepted_alg=>qr/^HS(256|384|512)$/); .Ve .IP "accepted_enc" 4 .IX Item "accepted_enc" \&\f(CW\*(C`undef\*(C'\fR (default) means accept all 'enc' algorithms .Sp \&\f(CW\*(C`string\*(C'\fR name of accepted 'enc' algorithm (only one) .Sp \&\f(CW\*(C`ARRAY ref\*(C'\fR a list of accepted 'enc' algorithms .Sp \&\f(CW\*(C`Regexp\*(C'\fR that has to match 'enc' algorithm name .Sp .Vb 5 \& my $payload = decode_jwt(token=>$t, key=>$k, accepted_enc=>\*(AqA192GCM\*(Aq); \& #or \& my $payload = decode_jwt(token=>$t, key=>$k, accepted_enc=>[\*(AqA192GCM\*(Aq,\*(AqA256GCM\*(Aq]); \& #or \& my $payload = decode_jwt(token=>$t, key=>$k, accepted_enc=>qr/^A(128|192|256)GCM$/); .Ve .IP "decode_payload" 4 .IX Item "decode_payload" \&\f(CW0\fR \- do not decode payload, return it as a raw string (octects). .Sp \&\f(CW1\fR \- decode payload from \s-1JSON\s0 string, return it as perl hash ref (or array ref) \- decode_json failure means fatal error (croak). .Sp \&\f(CW\*(C`undef\*(C'\fR (default) \- if possible decode payload from \s-1JSON\s0 string, if decode_json fails return payload as a raw string (octets). .IP "decode_header" 4 .IX Item "decode_header" \&\f(CW0\fR (default) \- do not return decoded header as a return value of \fBdecode_jwt()\fR .Sp \&\f(CW1\fR \- return decoded header as a return value of \fBdecode_jwt()\fR .Sp .Vb 3 \& my $payload = decode_jwt(token=>$t, key=>$k); \& #or \& my ($header, $payload) = decode_jwt(token=>$t, key=>$k, decode_header=>1); .Ve .IP "verify_iss" 4 .IX Item "verify_iss" \&\fB\s-1INCOMPATIBLE CHANGE\s0 in 0.024:\fR If \f(CW\*(C`verify_iss\*(C'\fR is specified and claim \f(CW\*(C`iss\*(C'\fR (Issuer) is completely missing it is a failure since 0.024 .Sp \&\f(CW\*(C`CODE ref\*(C'\fR \- subroutine (with 'iss' claim value passed as argument) should return \f(CW\*(C`true\*(C'\fR otherwise verification fails .Sp \&\f(CW\*(C`Regexp ref\*(C'\fR \- 'iss' claim value has to match given regexp otherwise verification fails .Sp \&\f(CW\*(C`Scalar\*(C'\fR \- 'iss' claim value has to be equal to given string (since 0.029) .Sp \&\f(CW\*(C`undef\*(C'\fR (default) \- do not verify 'iss' claim .IP "verify_aud" 4 .IX Item "verify_aud" \&\fB\s-1INCOMPATIBLE CHANGE\s0 in 0.024:\fR If \f(CW\*(C`verify_aud\*(C'\fR is specified and claim \f(CW\*(C`aud\*(C'\fR (Audience) is completely missing it is a failure since 0.024 .Sp \&\f(CW\*(C`CODE ref\*(C'\fR \- subroutine (with 'aud' claim value passed as argument) should return \f(CW\*(C`true\*(C'\fR otherwise verification fails .Sp \&\f(CW\*(C`Regexp ref\*(C'\fR \- 'aud' claim value has to match given regexp otherwise verification fails .Sp \&\f(CW\*(C`Scalar\*(C'\fR \- 'aud' claim value has to be equal to given string (since 0.029) .Sp \&\f(CW\*(C`undef\*(C'\fR (default) \- do not verify 'aud' claim .IP "verify_sub" 4 .IX Item "verify_sub" \&\fB\s-1INCOMPATIBLE CHANGE\s0 in 0.024:\fR If \f(CW\*(C`verify_sub\*(C'\fR is specified and claim \f(CW\*(C`sub\*(C'\fR (Subject) is completely missing it is a failure since 0.024 .Sp \&\f(CW\*(C`CODE ref\*(C'\fR \- subroutine (with 'sub' claim value passed as argument) should return \f(CW\*(C`true\*(C'\fR otherwise verification fails .Sp \&\f(CW\*(C`Regexp ref\*(C'\fR \- 'sub' claim value has to match given regexp otherwise verification fails .Sp \&\f(CW\*(C`Scalar\*(C'\fR \- 'sub' claim value has to be equal to given string (since 0.029) .Sp \&\f(CW\*(C`undef\*(C'\fR (default) \- do not verify 'sub' claim .IP "verify_jti" 4 .IX Item "verify_jti" \&\fB\s-1INCOMPATIBLE CHANGE\s0 in 0.024:\fR If \f(CW\*(C`verify_jti\*(C'\fR is specified and claim \f(CW\*(C`jti\*(C'\fR (\s-1JWT ID\s0) is completely missing it is a failure since 0.024 .Sp \&\f(CW\*(C`CODE ref\*(C'\fR \- subroutine (with 'jti' claim value passed as argument) should return \f(CW\*(C`true\*(C'\fR otherwise verification fails .Sp \&\f(CW\*(C`Regexp ref\*(C'\fR \- 'jti' claim value has to match given regexp otherwise verification fails .Sp \&\f(CW\*(C`Scalar\*(C'\fR \- 'jti' claim value has to be equal to given string (since 0.029) .Sp \&\f(CW\*(C`undef\*(C'\fR (default) \- do not verify 'jti' claim .IP "verify_iat" 4 .IX Item "verify_iat" \&\f(CW\*(C`undef\*(C'\fR \- Issued At 'iat' claim must be valid (not in the future) if present .Sp \&\f(CW0\fR (default) \- ignore 'iat' claim .Sp \&\f(CW1\fR \- require valid 'iat' claim .IP "verify_nbf" 4 .IX Item "verify_nbf" \&\f(CW\*(C`undef\*(C'\fR (default) \- Not Before 'nbf' claim must be valid if present .Sp \&\f(CW0\fR \- ignore 'nbf' claim .Sp \&\f(CW1\fR \- require valid 'nbf' claim .IP "verify_exp" 4 .IX Item "verify_exp" \&\f(CW\*(C`undef\*(C'\fR (default) \- Expiration Time 'exp' claim must be valid if present .Sp \&\f(CW0\fR \- ignore 'exp' claim .Sp \&\f(CW1\fR \- require valid 'exp' claim .IP "leeway" 4 .IX Item "leeway" Tolerance in seconds related to \f(CW\*(C`verify_exp\*(C'\fR, \f(CW\*(C`verify_nbf\*(C'\fR and \f(CW\*(C`verify_iat\*(C'\fR. Default is \f(CW0\fR. .IP "ignore_claims" 4 .IX Item "ignore_claims" \&\f(CW1\fR \- do not check claims (iat, exp, nbf, iss, aud, sub, jti), \fB\s-1BEWARE: DANGEROUS, UNSECURE\s0!!!\fR .Sp \&\f(CW0\fR (default) \- check claims .SS "encode_jwt" .IX Subsection "encode_jwt" .Vb 1 \& my $token = encode_jwt(%named_args); .Ve .PP Named arguments: .IP "payload" 4 .IX Item "payload" Value of this mandatory parameter can be a string/buffer or \s-1HASH\s0 ref or \s-1ARRAY\s0 ref .Sp .Vb 5 \& my $token = encode_jwt(payload=>"any raw data", key=>$k, alg=>\*(AqHS256\*(Aq); \& #or \& my $token = encode_jwt(payload=>{a=>1,b=>2}, key=>$k, alg=>\*(AqHS256\*(Aq); \& #or \& my $token = encode_jwt(payload=>[11,22,33,44], key=>$k, alg=>\*(AqHS256\*(Aq); .Ve .Sp \&\s-1HASH\s0 refs and \s-1ARRAY\s0 refs payloads are serialized as \s-1JSON\s0 strings .IP "alg" 4 .IX Item "alg" The 'alg' header value is mandatory for both \s-1JWE\s0 and \s-1JWS\s0 tokens. .Sp Supported \s-1JWE\s0 'alg' algorithms: .Sp .Vb 10 \& dir \& A128KW \& A192KW \& A256KW \& A128GCMKW \& A192GCMKW \& A256GCMKW \& PBES2\-HS256+A128KW \& PBES2\-HS384+A192KW \& PBES2\-HS512+A256KW \& RSA\-OAEP \& RSA\-OAEP\-256 \& RSA1_5 \& ECDH\-ES+A128KW \& ECDH\-ES+A192KW \& ECDH\-ES+A256KW \& ECDH\-ES .Ve .Sp Supported \s-1JWS\s0 algorithms: .Sp .Vb 10 \& none ... no integrity (NOTE: disabled by default) \& HS256 ... HMAC+SHA256 integrity \& HS384 ... HMAC+SHA384 integrity \& HS512 ... HMAC+SHA512 integrity \& RS256 ... RSA+PKCS1\-V1_5 + SHA256 signature \& RS384 ... RSA+PKCS1\-V1_5 + SHA384 signature \& RS512 ... RSA+PKCS1\-V1_5 + SHA512 signature \& PS256 ... RSA+PSS + SHA256 signature \& PS384 ... RSA+PSS + SHA384 signature \& PS512 ... RSA+PSS + SHA512 signature \& ES256 ... ECDSA + SHA256 signature \& ES256K ... ECDSA + SHA256 signature \& ES384 ... ECDSA + SHA384 signature \& ES512 ... ECDSA + SHA512 signature \& EdDSA ... Ed25519 signature .Ve .IP "enc" 4 .IX Item "enc" The 'enc' header is mandatory for \s-1JWE\s0 tokens. .Sp Supported 'enc' algorithms: .Sp .Vb 6 \& A128GCM \& A192GCM \& A256GCM \& A128CBC\-HS256 \& A192CBC\-HS384 \& A256CBC\-HS512 .Ve .IP "key" 4 .IX Item "key" A key used for token encryption (\s-1JWE\s0) or token signing (\s-1JWS\s0). The value depends on \f(CW\*(C`alg\*(C'\fR token header value. .Sp .Vb 10 \& JWS alg header key value \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& none no key required \& HS256 string (raw octects) of any length (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& HS384 dtto \& HS512 dtto \& RS256 private 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 private RSA key, see RS256 \& RS512 private RSA key, see RS256 \& PS256 private RSA key, see RS256 \& PS384 private RSA key, see RS256 \& PS512 private RSA key, see RS256 \& ES256 private 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 private ECC key, see ES256 \& ES384 private ECC key, see ES256 \& ES512 private ECC key, see ES256 \& EdDSA private Ed25519 key \& \& JWE alg header key value \& \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\-\- \& dir string (raw octects) or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq, length depends on \*(Aqenc\*(Aq algorithm \& A128KW string (raw octects) 16 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A192KW string (raw octects) 24 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A256KW string (raw octects) 32 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A128GCMKW string (raw octects) 16 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A192GCMKW string (raw octects) 24 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& A256GCMKW string (raw octects) 32 bytes (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& PBES2\-HS256+A128KW string (raw octects) of any length (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& PBES2\-HS384+A192KW string (raw octects) of any length (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& PBES2\-HS512+A256KW string (raw octects) of any length (or perl HASH ref with JWK, kty=>\*(Aqoct\*(Aq) \& RSA\-OAEP public RSA 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::RSA or Crypt::OpenSSL::RSA \& RSA\-OAEP\-256 public RSA key, see RSA\-OAEP \& RSA1_5 public RSA key, see RSA\-OAEP \& ECDH\-ES public ECC or X25519 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 \& ECDH\-ES+A128KW public ECC or X25519 key, see ECDH\-ES \& ECDH\-ES+A192KW public ECC or X25519 key, see ECDH\-ES \& ECDH\-ES+A256KW public ECC or X25519 key, see ECDH\-ES .Ve .IP "keypass" 4 .IX Item "keypass" When 'key' parameter is an encrypted private \s-1RSA\s0 or \s-1ECC\s0 key this optional parameter may contain a password for private key decryption. .IP "allow_none" 4 .IX Item "allow_none" \&\f(CW1\fR \- allow \s-1JWS\s0 with \f(CW\*(C`none\*(C'\fR 'alg' header value (which means that token has no signature), \fB\s-1BEWARE: DANGEROUS, UNSECURE\s0!!!\fR .Sp \&\f(CW0\fR (default) \- do not allow \s-1JWS\s0 with \f(CW\*(C`none\*(C'\fR 'alg' header value .IP "extra_headers" 4 .IX Item "extra_headers" This optional parameter may contain a \s-1HASH\s0 ref with items that will be added to \s-1JWT\s0 header. .Sp If you want to use PBES2\-based 'alg' like \f(CW\*(C`PBES2\-HS512+A256KW\*(C'\fR you can set \s-1PBES2\s0 salt len (p2s) in bytes and iteration count (p2c) via \f(CW\*(C`extra_headers\*(C'\fR like this: .Sp .Vb 2 \& my $token = encode_jwt(payload=>$p, key=>$k, alg=>\*(AqPBES2\-HS512+A256KW\*(Aq, extra_headers=>{p2c=8000, p2s=>32}); \& #NOTE: handling of p2s header is a special case, in the end it is replaced with the generated salt .Ve .IP "unprotected_headers" 4 .IX Item "unprotected_headers" A hash with additional integrity unprotected headers \- \s-1JWS\s0 and \s-1JWE\s0 (not available for \f(CW\*(C`compact\*(C'\fR serialization); .IP "shared_unprotected_headers" 4 .IX Item "shared_unprotected_headers" A hash with additional integrity unprotected headers \- \s-1JWE\s0 only (not available for \f(CW\*(C`compact\*(C'\fR serialization); .IP "aad" 4 .IX Item "aad" Additional Authenticated Data \- scalar value with any (even raw octects) data \- \s-1JWE\s0 only (not available for \f(CW\*(C`compact\*(C'\fR serialization); .IP "serialization" 4 .IX Item "serialization" Specify serialization method: \f(CW\*(C`compat\*(C'\fR (= default) for Compact \s-1JWS/JWE\s0 serialization or \f(CW\*(C`flattened\*(C'\fR for Flattened \s-1JWS/JWE JSON\s0 serialization. .Sp General \s-1JSON\s0 serialization is not supported yet. .IP "zip" 4 .IX Item "zip" Compression method, currently 'deflate' is the only one supported. \f(CW\*(C`undef\*(C'\fR (default) means no compression. .Sp .Vb 3 \& my $token = encode_jwt(payload=>$p, key=>$k, alg=>\*(AqHS256\*(Aq, zip=>\*(Aqdeflate\*(Aq); \& #or define compression level \& my $token = encode_jwt(payload=>$p, key=>$k, alg=>\*(AqHS256\*(Aq, zip=>[\*(Aqdeflate\*(Aq, 9]); .Ve .IP "auto_iat" 4 .IX Item "auto_iat" \&\f(CW1\fR \- set 'iat' (Issued At) claim to current time (epoch seconds since 1970) at the moment of token encoding .Sp \&\f(CW0\fR (default) \- do not set 'iat' claim .Sp \&\s-1NOTE:\s0 claims are part of the payload and can be used only if the payload is a \s-1HASH\s0 ref! .IP "relative_exp" 4 .IX Item "relative_exp" Set 'exp' claim (Expiration Time) to current time + \f(CW\*(C`relative_exp\*(C'\fR value (in seconds). .Sp \&\s-1NOTE:\s0 claims are part of the payload and can be used only if the payload is a \s-1HASH\s0 ref! .IP "relative_nbf" 4 .IX Item "relative_nbf" Set 'nbf' claim (Not Before) to current time + \f(CW\*(C`relative_nbf\*(C'\fR value (in seconds). .Sp \&\s-1NOTE:\s0 claims are part of the payload and can be used only if the payload is a \s-1HASH\s0 ref! .SH "SEE ALSO" .IX Header "SEE ALSO" Crypt::Cipher::AES, Crypt::AuthEnc::GCM, Crypt::PK::RSA, Crypt::PK::ECC, Crypt::KeyDerivation, Crypt::KeyWrap .SH "LICENSE" .IX Header "LICENSE" This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright (c) 2015\-2021 \s-1DCIT,\s0 a.s. / Karel Miko