]>
iEval git - authen-passphrase-scrypt.git/blob - Scrypt.pm
52fc683f3934e83f0573168fd5879a81d14eaae6
1 package Authen
:: Passphrase
:: Scrypt
;
8 use parent qw
/Exporter Authen::Passphrase/ ;
10 our @EXPORT = qw
/crypto_scrypt/ ;
11 our @EXPORT_OK = @EXPORT ;
12 our $VERSION = '0.002' ;
14 use Data
:: Entropy
:: Algorithms qw
/rand_bits/ ;
15 use Digest
:: SHA qw
/sha256 hmac_sha256/ ;
19 XSLoader
:: load
( 'Authen::Passphrase::Scrypt' , $VERSION );
21 use Object
:: Tiny qw
/data logN r p salt hmac passphrase/ ;
24 my ( $self , $passphrase ) = @_ ;
25 crypto_scrypt
( $passphrase , $self -> salt , ( 1 << $self -> logN ), $self -> r , $self -> p , 64 );
28 sub truncated_sha256
{
29 my $sha = sha256
shift ;
38 my ( $class , @args ) = @_ ;
39 if ( 'HASH' eq ref $args [ 0 ]) { # we were given a hash
42 unshift @args , logN
=> 14 , r
=> 16 , p
=> 1 ; # default values
44 $args { salt
} = rand_bits
256 unless exists $args { salt
};
45 my $self = bless \
%args , $class ;
47 croak
"passphrase not set" unless defined $self -> passphrase ;
49 my $data = "scrypt \x00 " . pack 'CNNa32' ,
50 $self -> logN , $self -> r , $self -> p , $self -> salt ;
51 $data .= truncated_sha256
$data ;
52 $self ->{ data
} = $data ;
53 $self ->{ hmac
} = hmac_sha256
$self -> data , truncate_hash
$self -> compute_hash ( $self -> passphrase );
58 my ( $class , $rfc2307 ) = @_ ;
59 croak
"Invalid Scrypt RFC2307" unless $rfc2307 =~ m
,^{ SCRYPT
}([ A
- Za
- z0
- 9 +/]{ 128 })$,;
60 my $data = decode_base64
$1 ;
61 my ( $scrypt , $logN , $r , $p , $salt , $cksum , $hmac ) =
62 unpack 'Z7CNNa32a16a32' , $data ;
63 croak
'Invalid Scrypt hash: should start with "scrypt"' unless $scrypt eq 'scrypt' ;
64 croak
'Invalid Scrypt hash: bad checksum' , unless $cksum eq truncated_sha256
( substr $data , 0 , 48 );
65 bless { data
=> ( substr $data , 0 , 64 ), logN
=> $logN , r
=> $r , p
=> $p , salt
=> $salt , hmac
=> $hmac }, $class ;
69 my ( $self , $passphrase ) = @_ ;
70 my $correct_hmac = hmac_sha256
$self -> data , truncate_hash
$self -> compute_hash ( $passphrase );
71 $self -> hmac eq $correct_hmac
76 '{SCRYPT}' . encode_base64
( $self -> data . $self -> hmac , '' )
80 croak __PACKAGE__
. " does not support crypt strings, use from_rfc2307 instead" ;
84 croak __PACKAGE__
. " does not support crypt strings, use as_rfc2307 instead" ;
94 Authen::Passphrase::Scrypt - passphrases using Tarsnap's scrypt algorithm
98 use Authen::Passphrase::Scrypt;
101 my $sc = Authen::Passphrase::Scrypt->new(
102 passphrase => 'correcthorsebatterystaple'
104 my $hash = $sc->as_rfc2307;
105 say "The given password hashes to $hash";
108 $sc = Authen::Passphrase::Scrypt->from_rfc2307($hash);
109 say 'The password was "correcthorsebatterystaple"'
110 if $sc->match('correcthorsebatterystaple');
111 say 'The password was "xkcd"' if $sc->match('xkcd');
114 my $sc = Authen::Passphrase::Scrypt->new(
115 passphrase => 'xkcd',
116 logN => 14, # General work factor
117 r => 16, # Memory work factor
118 p => 1, # CPU (parallellism) work factor
119 salt => 'SodiumChloride && sODIUMcHLORIDE', # Must be 32 bytes
121 say 'The given password now hashes to ', $sc->as_rfc2307;
125 B<This is experimental code, DO NOT USE in security-critical software>.
127 Scrypt is a key derivation function that was originally developed for
128 use in the Tarsnap online backup system and is designed to be far more
129 secure against hardware brute-force attacks than alternative functions
130 such as PBKDF2 or bcrypt.
132 Authen::Passphrase::Scrypt is a module for hashing and verifying
133 passphrases using scrypt. It offers the same interface as
134 L<Authen::Passphrase>. It is not however possible to use this module
135 from within L<Authen::Passphrase>. The methods are:
139 =item Authen::Passphrase::Scrypt->B<new>(I<%args>)
141 Creates a new L<Authen::Passphrase::Scrypt> from a given passphrase
142 and parameters. Use this to hash a passphrase. This function takes
143 either a key value list or a hashref. The arguments are:
149 The passphrase. Mandatory.
153 The general work factor (affects both CPU and memory cost). Defaults to 14
157 The blocksize (affects memory cost). Defaults to 16.
161 The parallelization factor (affects CPU cost). Defaults to 1.
165 A 32-byte string used as a salt. By default it is randomly generated
166 using L<Data::Entropy>.
170 All of the parameters change the result of the hash. They are all
171 stored in the hash, so there is no need to store them separately (or
172 provide them to the hash verification methods).
174 It is normally sufficient to only use the B<logN> parameter to control
175 the speed of scrypt. B<r> and B<p> are intended to be used only for
176 fine-tuning: if scrypt uses too much memory but not enough CPU,
177 decrease logN and increase p; if scrypt uses too much CPU but not
178 enough memory, decrease logN and increase r.
180 Note that C<< 2^logN >> must fit in 64 bits and C<< r * p < 2^30 >>.
182 =item $sc->B<as_rfc2307>
184 Returns the hash of the passphrase, in RFC2307 format. This is
185 "{SCRYPT}" followed by the base64-encoded 96-byte result described here: L<https://security.stackexchange.com/questions/88678/why-does-node-js-scrypt-function-use-hmac-this-way/91050>
187 =item Authen::Passphrase::Scrypt->B<from_rfc2307>(I<$rfc2307>)
189 Creates a new L<Authen::Passphrase::Scrypt> from a hash in RFC2307
190 format. Use this to verify if a passphrase matches a hash.
192 =item $sc->B<match>(I<$passphrase>)
194 Returns true if the given passphrase matches the hash, false
197 =item Authen::Passphrase::Scrypt->from_crypt
201 These functions both croak. They are provided for compatibility with
202 the Authen::Passphrase interface.
208 L<Authen::Passphrase>,
209 L<https://www.tarsnap.com/scrypt.html>,
210 L<https://www.npmjs.com/package/scrypt>
214 Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
216 =head1 COPYRIGHT AND LICENSE
218 Copyright (C) 2017-2018 by Marius Gavrilescu
220 This library is free software; you can redistribute it and/or modify
221 it under the same terms as Perl itself, either Perl version 5.24.1 or,
222 at your option, any later version of Perl 5 you may have available.
This page took 0.05878 seconds and 3 git commands to generate.