NAME

Crypt::JWS::OpenSSL - Encode, decode and verify signed compact JWTs using OpenSSL modules

VERSION

version 0.003

SYNOPSYS

use Crypt::JWS::OpenSSL;
my $cjos = Crypt::JWS::OpenSSL->new;

my $token = $cjos->encode(
    header => $header_ref,
    claims => $claims_ref,
    secret => $key,
);

if(!$token) {
   $logger->log_error( $cjos->last_error)
}

###################
## in some module
###################

use Crypt::JWS::OpenSSL;

has verifier => ( is => 'ro', default => sub { Crypt::JWS::OpenSSL->new } );

sub permissions_from_token {
  my($self, $token) = @_;
  my $unverified = $self->verifier->decode_unverified(token => $token);
  unless($unverified) {
      my $reason = $self->verifier->last_error;
      ## inspect and log reason
      return undef;
  }
  my ($secret, $permissions) = $self->examine_token(
      $unverified->{header}, $unverified->{claims}
  );
  unless($secret && $permissions) {
    ## no secret and permissions
    return undef;
  }
  my $ok = $self->verifier->verify(
    secret      => $secret,
    verifytoken => $unverified->{verifytoken}
  );
  unless( $ok && $ok eq '1' ) {
     my $reason = $self->verifier->last_error;
     ## inspect and log reason
     return undef;
  }
  ## log access
  ## grant permissions
  return $permissions;
}

DESCRIPTION

Encode, decode and verify signed compact JWTs using Crypt::OpenSSL modules.

SUPPORTED ALGORITHMS

Shared HMAC secret

HS256 HS384 HS512

These algorithms do not require any Crypt::OpenSSL modules. They are included for completeness.

RSA

RS256 RS384 RS512 PS256 PS384 PS512

ECDSA

ES256 ES384 ES512

METHODS

encode

$cjo->encode( header => $header, claims => $claims, secret => $secret )

Accepts a hash reference or an even numbered list.

Returns a signed compact JWT on success or undefined on error.

parameters

A reference to a hash containing the header elements for the JWS.

At a minumim this must contain a alg key/value with a value of one of the supported algorithms.

If no typ key/value is present, a default of typ => 'JWT' will be added.

claims

A reference to a hash containing the claim elements for the JWS.

This must contain at least 1 key/value pair.

secret

The secret used to sign the JWS.

For shared HMAC algorithms, this is a scalar containing the raw shared secret.

For RSA and ECDSA algorithms this can be a scalar containing the full text of a pem encoded private key.

A reference to a hash containing the elements of a JWK can also be used.

For a regularly used private key it is more efficient to store the key as pem encoded text. You can convert a JWK using Crypt::JWS::OpenSSL::Util::JWK.

Where a kid is required by a verifying recipient, it must always be added to the header hash. It will not be taken from the value within a JWK.

For errors and exceptions see error handling

decode_unverified

$cjo->decode_unverified( token => $tokenreceived )

Accepts a hash reference or an even numbered list.

On success, returns the decocoded header and claims hash references together with a 'verifytoken' that can be passed to "verify".

Returns undefined on error.

parameters

token

A token to decode.

Returned hash reference structure

{
  header      => { ... },
  claims      => { ... },
  verifytoken => 'xxxxxxxxxxxx....'
}

After inspecting the header and claims, the appropriate secret can be passed to "verify" to verify the signature.

For errors and exceptions see error handling

verify

$cjo->verify( verifytoken => $verifytoken, secret => $secret )

Accepts a hash reference or an even numbered list.

On success returns 1. On failure or error returns 0 or undefined.

parameters

verifytoken

The verifytoken member of the hash reference returned from a prior call to "decode_unverified".

secret

The appropriate public key or shared HMAC secret determined by inspection of the header and claims returned from a prior call to "decode_unverified".

The secret for an RSA or ECDSA algorithm can be a scalar containing the full text of a pem encoded public key.

A reference to a hash containing the elements of a JWK can also be used.

For a regularly used public key it is more efficient to store the key as pem encoded text. You can convert a JWK using Crypt::JWS::OpenSSL::Util::JWK.

For errors and exceptions see error handling

PROPERTIES

last_error

Read only.

When any of the methods "encode", "decode_unverified", "verify" return undefined or false, the reason is available in "last_error".

see error handling

see also "throw_errors"

throw_errors

Read write.

Default value 0 (false)

While "throw_errors" is false, errors or exceptions encountered in "encode", "decode_unverified" and "verify" are caught and stored in "last_error" available to read when the method returns.

If throw_errors is set to 1 ( true ) the module croaks when errors and exceptions are encountered in "encode", "decode_unverified" and "verify".

see error handling

see also "last_error"

can_use_pkcs1_padding

Read only.

Returns true ( 1 ) if Crypt::OpenSSL::RSA can 'use_pkcs1_padding'.

Returns false ( 0 ) if Crypt::OpenSSL::RSA cannot 'use_pkcs1_padding'.

This padding method is necessary for algorithms

RS256, RS384, and RS512

It is likely that your version of Crypt::OpenSSL::RSA supports 'use_pkcs1_padding' as only a couple of short lived versions did not.

can_use_pkcs1_pss_padding

Returns true ( 1 ) if Crypt::OpenSSL::RSA can 'use_pkcs1_pss_padding'.

Returns false ( 0 ) if Crypt::OpenSSL::RSA cannot 'use_pkcs1_pss_padding'.

This padding method is necessary for algorithms

PS256, PS384, and PS512

This padding method requires OpenSSL 3.x and Crypt::OpenSSL::RSA version greater than or equal to 0.38

See also Crypt::JWS::OpenSSL::Local

JSON

Read only. An instance of a JSON encoder / decoder

The default is JSON::MaybeXS->new->utf8(1);

If you have a partcular perference for a JSON module, 'use' that before Crypt::JWS::OpenSSL or provide your own instance.

use JSON::XS;
use Crypt::JWS::OpenSSL;

## OR

use Crypt::JWS::OpenSSL;
use JSON::XS;

my $cjos = Crypt::JWS::OpenSSL->new( JSON => JSON::XS->new->utf8(1) );

ERROR HANDLING

When "throw_errors" is 0 ( the default ) if errors or exceptions are encountered in the methods "encode", "decode_unverified" and "verify", the methods return undefined or false and the reason is available in "last_error".

If "throw_errors" is set to 1, the methods croak on errors or exceptions.

SEE ALSO

Crypt OpenSSL modules used

Crypt::OpenSSL::RSA

Crypt::OpenSSL::EC

Crypt::OpenSSL::ECDSA

Alternatives for JWT handling.

CryptX ( wraps the LibTomCrypt library )

Crypt::Perl ( pure perl )

AUTHOR

Mark Dootson <mdootson@cpan.org>

COPYRIGHT AND LICENSE

Copyright (C) 2026 by Mark Dootson

This library is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.