]>
iEval git - authen-passphrase-scrypt.git/blob - Scrypt.pm
060e2c88eed613216d0d5fbf9c16564b455a97e2
1 package Authen
:: Passphrase
:: Scrypt
;
8 use parent qw
/Exporter Authen::Passphrase Class::Accessor::Fast/ ;
10 our @EXPORT = qw
/crypto_scrypt/ ;
11 our @EXPORT_OK = @EXPORT ;
12 our $VERSION = '0.001' ;
14 use Data
:: Entropy
:: Algorithms qw
/rand_bits/ ;
15 use Digest
:: SHA qw
/sha256 hmac_sha256/ ;
19 XSLoader
:: load
( 'Authen::Passphrase::Scrypt' , $VERSION );
21 __PACKAGE__
-> mk_accessors ( 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 my $self = $class -> SUPER :: new
( @args );
41 $self -> logN ( 14 ) unless defined $self -> logN ;
42 $self -> r ( 16 ) unless defined $self -> r ;
43 $self -> p ( 1 ) unless defined $self -> p ;
44 croak
"passphrase not set" unless defined $self -> passphrase ;
45 $self -> salt ( rand_bits
256 ) unless $self -> salt ;
47 my $data = "scrypt \x00 " . pack 'CNNa32' ,
48 $self -> logN , $self -> r , $self -> p , $self -> salt ;
49 $data .= truncated_sha256
$data ;
51 $self -> hmac ( hmac_sha256
$self -> data , truncate_hash
$self -> compute_hash ( $self -> passphrase ));
56 my ( $class , $rfc2307 ) = @_ ;
57 croak
"Invalid Scrypt RFC2307" unless $rfc2307 =~ m
,^{ SCRYPT
}([ A
- Za
- z0
- 9 +/]{ 128 })$,;
58 my $data = decode_base64
$1 ;
59 my ( $scrypt , $logN , $r , $p , $salt , $cksum , $hmac ) =
60 unpack 'Z7CNNa32a16a32' , $data ;
61 croak
'Invalid Scrypt hash: should start with "scrypt"' unless $scrypt eq 'scrypt' ;
62 croak
'Invalid Scrypt hash: bad checksum' , unless $cksum eq truncated_sha256
( substr $data , 0 , 48 );
63 $class -> SUPER :: new
({ data
=> ( substr $data , 0 , 64 ), logN
=> $logN , r
=> $r , p
=> $p , salt
=> $salt , hmac
=> $hmac });
67 my ( $self , $passphrase ) = @_ ;
68 my $correct_hmac = hmac_sha256
$self -> data , truncate_hash
$self -> compute_hash ( $passphrase );
69 $self -> hmac eq $correct_hmac
74 '{SCRYPT}' . encode_base64
( $self -> data . $self -> hmac , '' )
78 croak __PACKAGE__
. " does not support crypt strings, use from_rfc2307 instead" ;
82 croak __PACKAGE__
. " does not support crypt strings, use as_rfc2307 instead" ;
92 Authen::Passphrase::Scrypt - passphrases using Tarsnap's scrypt algorithm
96 use Authen::Passphrase::Scrypt;
99 my $sc = Authen::Passphrase::Scrypt->new({
100 passphrase => 'correcthorsebatterystaple'
102 my $hash = $sc->as_rfc2307;
103 say "The given password hashes to $hash";
106 $sc = Authen::Passphrase::Scrypt->from_rfc2307($hash);
107 say 'The password was "correcthorsebatterystaple"'
108 if $sc->match('correcthorsebatterystaple');
109 say 'The password was "xkcd"' if $sc->match('xkcd');
112 my $sc = Authen::Passphrase::Scrypt->new({
113 passphrase => 'xkcd',
114 logN => 14, # General work factor
115 r => 16, # Memory work factor
116 p => 1, # CPU (parallellism) work factor
117 salt => 'SodiumChloride && sODIUMcHLORIDE', # Must be 32 bytes
119 say 'The given password now hashes to ', $sc->as_rfc2307;
123 B<This is experimental code, DO NOT USE in security-critical software>.
125 Scrypt is a key derivation function that was originally developed for
126 use in the Tarsnap online backup system and is designed to be far more
127 secure against hardware brute-force attacks than alternative functions
128 such as PBKDF2 or bcrypt.
130 Authen::Passphrase::Scrypt is a module for hashing and verifying
131 passphrases using scrypt. It offers the same interface as
132 L<Authen::Passphrase>. It is not however possible to use this module
133 from within L<Authen::Passphrase>. The methods are:
137 =item Authen::Passphrase::Scrypt->B<new>(I<\%args>)
139 Creates a new L<Authen::Passphrase::Scrypt> from a given passphrase
140 and parameters. Use this to hash a passphrase. The arguments are:
146 The passphrase. Mandatory.
150 The general work factor (affects both CPU and memory cost). Defaults to 14
154 The blocksize (affects memory cost). Defaults to 16.
158 The parallelization factor (affects CPU cost). Defaults to 1.
162 A 32-byte string used as a salt. By default it is randomly generated
163 using L<Data::Entropy>.
167 All of the parameters change the result of the hash. They are all
168 stored in the hash, so there is no need to store them separately (or
169 provide them to the hash verification methods).
171 It is normally sufficient to only use the B<logN> parameter to control
172 the speed of scrypt. B<r> and B<p> are intended to be used only for
173 fine-tuning: if scrypt uses too much memory but not enough CPU,
174 decrease logN and increase p; if scrypt uses too much CPU but not
175 enough memory, decrease logN and increase r.
177 =item $sc->B<as_rfc2307>
179 Returns the hash of the passphrase, in RFC2307 format. This is
180 "{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>
182 =item Authen::Passphrase::Scrypt->B<from_rfc2307>(I<$rfc2307>)
184 Creates a new L<Authen::Passphrase::Scrypt> from a hash in RFC2307
185 format. Use this to verify if a passphrase matches a hash.
187 =item $sc->B<match>(I<$passphrase>)
189 Returns true if the given passphrase matches the hash, false
192 =item Authen::Passphrase::Scrypt->from_crypt
195 These functions both croak. They are provided for compatibility with
196 the Authen::Passphrase interface.
202 L<Authen::Passphrase>,
203 L<https://www.tarsnap.com/scrypt.html>,
204 L<https://www.npmjs.com/package/scrypt>
208 Marius Gavrilescu, E<lt>marius@ieval.roE<gt>
210 =head1 COPYRIGHT AND LICENSE
212 Copyright (C) 2017 by Marius Gavrilescu
214 This library is free software; you can redistribute it and/or modify
215 it under the same terms as Perl itself, either Perl version 5.24.1 or,
216 at your option, any later version of Perl 5 you may have available.
This page took 0.061689 seconds and 3 git commands to generate.