Crypt-PBE
view release on metacpan or search on metacpan
lib/Crypt/PBE/PBES2.pm view on Meta::CPAN
package Crypt::PBE::PBES2;
use strict;
use warnings;
use utf8;
use Carp;
use Crypt::CBC;
use Exporter qw(import);
use Crypt::PBE::PBKDF2;
our $VERSION = '0.103';
use constant KEY_SIZE => {
'aes-128' => 16,
'aes-192' => 24,
'aes-256' => 32,
};
use constant ENCRYPTION => {
'aes-128' => 'Crypt::OpenSSL::AES',
'aes-192' => 'Crypt::OpenSSL::AES',
'aes-256' => 'Crypt::OpenSSL::AES',
};
use constant HMAC => qw( hmac-sha1 hmac-224 hmac-sha256 hmac-sha384 hmac-sha512 );
sub new {
my ( $class, %params ) = @_;
my $self = {
password => $params{password} || croak('Specify password'),
hmac => $params{hmac} || croak('Specify HMAC digest algorithm'),
encryption => $params{encryption} || croak('Specify encryption method'),
count => $params{count} || 1_000,
dk_len => 0,
};
my $dk_len = KEY_SIZE->{ $params{encryption} };
if ( !$dk_len ) {
croak('Unknown encryption method');
}
$self->{dk_len} = $dk_len;
return bless $self, $class;
}
sub encrypt {
my ( $self, $data ) = @_;
my $salt = Crypt::CBC->random_bytes(16);
my $iv = Crypt::CBC->random_bytes(16);
my $key = pbkdf2(
prf => $self->{hmac},
password => $self->{password},
salt => $salt,
dk_len => $self->{dk_len},
count => $self->{count}
);
my $cipher = Crypt::CBC->new(
-key => $key,
-keysize => length($key),
-iv => $iv,
-header => 'none',
-literal_key => 1,
-cipher => ENCRYPTION->{ $self->{encryption} }
);
my $encrypted = $cipher->encrypt($data);
my @result = ( $salt, $iv, $encrypted );
return wantarray ? @result : join( '', @result );
}
sub decrypt {
my ( $self, $salt, $iv, $encrypted ) = @_;
if ( !$iv && !$encrypted ) {
my $data = $salt;
$salt = substr( $data, 0, 16 );
$iv = substr( $data, 16, 16 );
$encrypted = substr( $data, 32 );
}
my $key = pbkdf2(
prf => $self->{hmac},
password => $self->{password},
salt => $salt,
dk_len => $self->{dk_len},
count => $self->{count}
);
my $cipher = Crypt::CBC->new(
-key => $key,
-keysize => length($key),
-iv => $iv,
-header => 'none',
-literal_key => 1,
-cipher => ENCRYPTION->{ $self->{encryption} }
);
return $cipher->decrypt($encrypted);
}
1;
=head1 NAME
Crypt::PBE::PBES2 - Perl extension for PKCS #5 Password-Based Encryption Schema 2 (PBES2)
=head1 SYNOPSIS
use Crypt::PBE::PBES2;
my $pbes2 = Crypt::PBE::PBES2->new(
'hmac' => 'hmac-sha256',
'encryption' => 'aes-128',
'password' => 'mypassword'
);
my $encrypted = $pbes2->encrypt('secret');
say $pbes2->decrypt($encrypted); # secret
=head1 DESCRIPTION
PBES2 combines a password-based key derivation function, which shall be PBKDF2
with an underlying encryption scheme. The key length and any other parameters
for the underlying encryption scheme depend on the scheme.
PBES2 is recommended for new applications.
=head1 CONSTRUCTOR
=head2 Crypt::PBE::PBES2->new ( %params )
Params:
=over 4
=item * C<password> : The password to use for the derivation
=item * C<hmac> : HMAC digest algorithm ("hmac-sha1", "hmac-sha224", "hmac-sha256", "hmac-sha384" or "hmac-512")
=item * C<encryption> : Encryption method ("aes-128", "aes-192" or "aes-256")
=item * C<count> : The number of internal iteractions to perform for the derivation key (default "1_000")
=back
( run in 1.082 second using v1.01-cache-2.11-cpan-e1769b4cff6 )