Crypt-OpenToken
view release on metacpan or search on metacpan
lib/Crypt/OpenToken.pm view on Meta::CPAN
$digest->add($fields->{iv}) if ($fields->{iv_len} > 0);
$digest->add($fields->{key}) if ($fields->{key_len} > 0);
$digest->add($plaintext);
return $digest->digest;
}
sub _unpack {
my ($self, $token_str) = @_;
use bytes;
my ($otk, $ver, $cipher, $hmac, $iv, $key, $payload)
= unpack(TOKEN_PACK, $token_str);
unless ($otk eq 'OTK') {
croak "invalid literal identifier in OTK; '$otk'";
}
unless ($ver == 1) {
croak "unsupported OTK version; '$ver'";
}
return {
version => $ver,
cipher => $cipher,
hmac => $hmac,
iv_len => length($iv),
iv => $iv,
key_len => length($key),
key => $key,
payload_len => length($payload),
payload => $payload,
};
}
sub _pack {
my ($self, %fields) = @_;
# truncate to specified lengths
for (qw(iv key payload)) {
substr($fields{$_}, $fields{ $_ . "_len" }) = '';
}
my $token_str = pack(TOKEN_PACK,
'OTK', @fields{qw(version cipher hmac iv key payload)}
);
return $token_str;
}
# Custom Base64 decoding; OTK has some oddities in how they encode things
# using Base64.
sub _base64_decode {
my ($self, $token_str) = @_;
# fixup: convert trailing "*"s into "="s (OTK specific encoding)
$token_str =~ s/(\*+)$/'=' x length($1)/e;
# fixup: convert "_" to "/" (PingId PHP bindings encode this way)
# fixup: convert "-" to "+" (PingId PHP bindings encode this way)
$token_str =~ tr{_-}{/+};
# Base64 decode it, and we're done.
my $decoded = decode_base64($token_str);
return $decoded;
}
# Custom Base64 encoding; OTK has some oddities in how they encode things
# using Base64.
sub _base64_encode {
my ($self, $token_str) = @_;
# Base64 encode the token string
my $encoded = encode_base64($token_str, '');
# fixup: convert "+" to "-" (PingId PHP bindings encode this way)
# fixup: convert "/" to "_" (PingId PHP bindings encode this way)
$encoded =~ tr{/+}{_-};
# fixup: convert trailing "="s to "*"s (OTK specific encoding)
$encoded =~ s/(\=+)$/'*' x length($1)/e;
return $encoded;
}
no Moose;
1;
=for stopwords OpenTokens Socialtext PingFederate TripleDES Base64 decrypts merchantability
=head1 NAME
Crypt::OpenToken - Perl implementation of Ping Identity's "OpenToken"
=head1 SYNOPSIS
use Crypt::OpenToken;
my $data = {
foo => 'bar',
bar => 'baz',
};
# create an OpenToken factory based on a given shared password
my $factory = Crypt::OpenToken->new(password => 'abc123');
# encrypt a hash-ref of data into an OpenToken.
my $token_str = $factory->create(
Crypt::OpenToken::CIPHER_AES128,
$data,
);
# decrypt an OpenToken, check if its valid, and get data back out
my $token = $factory->parse($token_str);
if ($token->is_valid) {
$data = $token->data();
}
=head1 DESCRIPTION
This module provides a Perl implementation of the "OpenToken" standard as
defined by Ping Identity in their IETF Draft.
=head1 METHODS
( run in 1.039 second using v1.01-cache-2.11-cpan-df04353d9ac )