5 # ABSTRACT: Minimalist PBKDF2 (RFC 2898) with HMAC-SHA1 or HMAC-SHA2
7 our $VERSION = '0.005';
10 use Exporter 5.57 qw/import/;
12 our @EXPORT_OK = qw/derive derive_hex verify verify_hex hmac digest_fcn/;
14 my ( $BACKEND, $LOAD_ERR );
15 for my $mod (qw/Digest::SHA Digest::SHA::PurePerl/) {
16 $BACKEND = $mod, last if eval "require $mod; 1";
19 die $LOAD_ERR if !$BACKEND;
21 #--------------------------------------------------------------------------#
22 # constants and lookup tables
23 #--------------------------------------------------------------------------#
25 # function coderef placeholder, block size in bytes, digest size in bytes
27 'SHA-1' => [ undef, 64, 20 ],
28 'SHA-224' => [ undef, 64, 28 ],
29 'SHA-256' => [ undef, 64, 32 ],
30 'SHA-384' => [ undef, 128, 48 ],
31 'SHA-512' => [ undef, 128, 64 ],
34 for my $type ( keys %DIGEST_TYPES ) {
36 ( my $name = lc $type ) =~ s{-}{};
37 $DIGEST_TYPES{$type}[0] = \&{"$BACKEND\::$name"};
40 my %INT = map { $_ => pack( "N", $_ ) } 1 .. 16;
42 #--------------------------------------------------------------------------#
44 #--------------------------------------------------------------------------#
48 #pod $dk = derive( $type, $password, $salt, $iterations, $dk_length )
50 #pod The C<derive> function outputs a binary string with the derived key.
51 #pod The first argument indicates the digest function to use. It must be one
52 #pod of: SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512.
54 #pod If a password or salt are not provided, they default to the empty string, so
55 #pod don't do that! L<RFC 2898
56 #pod recommends|https://tools.ietf.org/html/rfc2898#section-4.1> a random salt of at
57 #pod least 8 octets. If you need a cryptographically strong salt, consider
58 #pod L<Crypt::URandom>.
60 #pod The password and salt should encoded as octet strings. If not (i.e. if
61 #pod Perl's internal 'UTF8' flag is on), then an exception will be thrown.
63 #pod The number of iterations defaults to 1000 if not provided. If the derived
64 #pod key length is not provided, it defaults to the output size of the digest
70 my ( $type, $passwd, $salt, $iterations, $dk_length ) = @_;
72 my ( $digester, $block_size, $digest_length ) = digest_fcn($type);
74 $passwd = '' unless defined $passwd;
75 $salt = '' unless defined $salt;
77 $dk_length ||= $digest_length;
79 # we insist on octet strings for password and salt
80 Carp::croak("password must be an octet string, not a character string")
81 if utf8::is_utf8($passwd);
82 Carp::croak("salt must be an octet string, not a character string")
83 if utf8::is_utf8($salt);
85 my $key = ( length($passwd) > $block_size ) ? $digester->($passwd) : $passwd;
86 my $passes = int( $dk_length / $digest_length );
87 $passes++ if $dk_length % $digest_length; # need part of an extra pass
90 for my $i ( 1 .. $passes ) {
91 $INT{$i} ||= pack( "N", $i );
92 my $digest = my $result =
93 "" . hmac( $salt . $INT{$i}, $key, $digester, $block_size );
94 for my $iter ( 2 .. $iterations ) {
95 $digest = hmac( $digest, $key, $digester, $block_size );
101 return substr( $dk, 0, $dk_length );
104 #pod =func derive_hex
106 #pod Works just like L</derive> but outputs a hex string.
110 sub derive_hex { unpack( "H*", &derive ) }
114 #pod $bool = verify( $dk, $type, $password, $salt, $iterations, $dk_length );
116 #pod The C<verify> function checks that a given derived key (in binary form) matches
117 #pod the password and other parameters provided using a constant-time comparison
120 #pod The first parameter is the derived key to check. The remaining parameters
121 #pod are the same as for L</derive>.
126 my ( $dk1, @derive_args ) = @_;
128 my $dk2 = derive(@derive_args);
130 # shortcut if input dk is the wrong length entirely; this is not
131 # constant time, but this doesn't really give much away as
132 # the keys are of different types anyway
134 return unless length($dk1) == length($dk2);
136 # if lengths match, do constant time comparison to avoid timing attacks
138 for my $i ( 0 .. length($dk1) - 1 ) {
139 $match &= ( substr( $dk1, $i, 1 ) eq substr( $dk2, $i, 1 ) ) ? 1 : 0;
145 #pod =func verify_hex
147 #pod Works just like L</verify> but the derived key must be a hex string (without a
153 my $dk = pack( "H*", shift );
154 return verify( $dk, @_ );
157 #pod =func digest_fcn
159 #pod ($fcn, $block_size, $digest_length) = digest_fcn('SHA-1');
160 #pod $digest = $fcn->($data);
162 #pod This function is used internally by PBKDF2::Tiny, but made available in case
163 #pod it's useful to someone.
165 #pod Given one of the valid digest types, it returns a function reference that
166 #pod digests a string of data. It also returns block size and digest length for that
174 Carp::croak("Digest function '$type' not supported")
175 unless exists $DIGEST_TYPES{$type};
177 return @{ $DIGEST_TYPES{$type} };
182 #pod $key = $digest_fcn->($key) if length($key) > $block_size;
183 #pod $hmac = hmac( $data, $key, $digest_fcn, $block_size );
185 #pod This function is used internally by PBKDF2::Tiny, but made available in case
186 #pod it's useful to someone.
188 #pod The first two arguments are the data and key inputs to the HMAC function. Both
189 #pod should be encoded as octet strings, as underlying HMAC/digest functions may
190 #pod croak or may give unexpected results if Perl's internal UTF-8 flag is on.
192 #pod B<Note>: if the key is longer than the digest block size, it must be
193 #pod preprocessed using the digesting function.
195 #pod The third and fourth arguments must be a digesting code reference (from
196 #pod L</digest_fcn>) and block size.
200 # hmac function adapted from Digest::HMAC by Graham Barr and Gisle Aas.
201 # Compared to that implementation, this *requires* a preprocessed
202 # key and block size, which makes iterative hmac slightly more efficient.
204 my ( $data, $key, $digest_func, $block_size ) = @_;
206 my $k_ipad = $key ^ ( chr(0x36) x $block_size );
207 my $k_opad = $key ^ ( chr(0x5c) x $block_size );
209 &$digest_func( $k_opad, &$digest_func( $k_ipad, $data ) );
215 # vim: ts=4 sts=4 sw=4 et:
225 PBKDF2::Tiny - Minimalist PBKDF2 (RFC 2898) with HMAC-SHA1 or HMAC-SHA2
233 use PBKDF2::Tiny qw/derive verify/;
235 my $dk = derive( 'SHA-1', $pass, $salt, $iters );
237 if ( verify( $dk, 'SHA-1', $pass, $salt, $iters ) ) {
238 # password is correct
243 This module provides an L<RFC 2898|https://tools.ietf.org/html/rfc2898>
244 compliant PBKDF2 implementation using HMAC-SHA1 or HMAC-SHA2 in under 100 lines
245 of code. If you are using Perl 5.10 or later, it uses only core Perl modules.
246 If you are on an earlier version of Perl, you need L<Digest::SHA> or
247 L<Digest::SHA::PurePerl>.
249 All documented functions are optionally exported. No functions are exported by default.
255 $dk = derive( $type, $password, $salt, $iterations, $dk_length )
257 The C<derive> function outputs a binary string with the derived key.
258 The first argument indicates the digest function to use. It must be one
259 of: SHA-1, SHA-224, SHA-256, SHA-384, or SHA-512.
261 If a password or salt are not provided, they default to the empty string, so
262 don't do that! L<RFC 2898
263 recommends|https://tools.ietf.org/html/rfc2898#section-4.1> a random salt of at
264 least 8 octets. If you need a cryptographically strong salt, consider
267 The password and salt should encoded as octet strings. If not (i.e. if
268 Perl's internal 'UTF8' flag is on), then an exception will be thrown.
270 The number of iterations defaults to 1000 if not provided. If the derived
271 key length is not provided, it defaults to the output size of the digest
276 Works just like L</derive> but outputs a hex string.
280 $bool = verify( $dk, $type, $password, $salt, $iterations, $dk_length );
282 The C<verify> function checks that a given derived key (in binary form) matches
283 the password and other parameters provided using a constant-time comparison
286 The first parameter is the derived key to check. The remaining parameters
287 are the same as for L</derive>.
291 Works just like L</verify> but the derived key must be a hex string (without a
296 ($fcn, $block_size, $digest_length) = digest_fcn('SHA-1');
297 $digest = $fcn->($data);
299 This function is used internally by PBKDF2::Tiny, but made available in case
300 it's useful to someone.
302 Given one of the valid digest types, it returns a function reference that
303 digests a string of data. It also returns block size and digest length for that
308 $key = $digest_fcn->($key) if length($key) > $block_size;
309 $hmac = hmac( $data, $key, $digest_fcn, $block_size );
311 This function is used internally by PBKDF2::Tiny, but made available in case
312 it's useful to someone.
314 The first two arguments are the data and key inputs to the HMAC function. Both
315 should be encoded as octet strings, as underlying HMAC/digest functions may
316 croak or may give unexpected results if Perl's internal UTF-8 flag is on.
318 B<Note>: if the key is longer than the digest block size, it must be
319 preprocessed using the digesting function.
321 The third and fourth arguments must be a digesting code reference (from
322 L</digest_fcn>) and block size.
345 =for :stopwords cpan testmatrix url annocpan anno bugtracker rt cpants kwalitee diff irc mailto metadata placeholders metacpan
349 =head2 Bugs / Feature Requests
351 Please report any bugs or feature requests through the issue tracker
352 at L<https://github.com/dagolden/PBKDF2-Tiny/issues>.
353 You will be notified automatically of any progress on your issue.
357 This is open source software. The code repository is available for
358 public review and contribution under the terms of the license.
360 L<https://github.com/dagolden/PBKDF2-Tiny>
362 git clone https://github.com/dagolden/PBKDF2-Tiny.git
366 David Golden <dagolden@cpan.org>
368 =head1 COPYRIGHT AND LICENSE
370 This software is Copyright (c) 2014 by David Golden.
372 This is free software, licensed under:
374 The Apache License, Version 2.0, January 2004