Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision c157c911

Von Moritz Bunkus vor fast 9 Jahren hinzugefügt

  • ID c157c911ac9175e4838990d051c594dd5eec7e21
  • Vorgänger 92deb643
  • Nachfolger 69af5044

Passwörter: Hash-Verfahren PBKDF2 unterstützen und als Standard nutzen

Der aktuelle Stand der Technik sind die SHA-*-Varianten schon lange
nicht mehr. In der Zwischenzeit wurden der PBKDF2-Mechanismus
entwickelt, um schnelles Berechnen zu erschweren. Noch neuer und in
ASICs noch schwerer umsetzbar sind BCrypt und SCrypt, für die es aber
noch keine weit verbreiteten Perl-Module gibt.

Unterschiede anzeigen:

SL/Auth/Password.pm
5 5
use Carp;
6 6
use Digest::MD5 ();
7 7
use Digest::SHA ();
8
use Encode ();
9
use PBKDF2::Tiny ();
10

  
11
sub hash_pkkdf2 {
12
  my ($class, %params) = @_;
13

  
14
  # PBKDF2::Tiny expects data to be in octets. Therefore we must
15
  # encode everything we hand over (login, password) to UTF-8.
16

  
17
  # This hash method uses a random hash and not just the user's login
18
  # for its salt. This is due to the official recommendation that at
19
  # least eight octets of random data should be used. Therefore we
20
  # must store the salt together with the hashed password. The format
21
  # in the database is:
22

  
23
  # {PBKDF2}salt-in-hex:hash-in-hex
24

  
25
  my $salt;
26

  
27
  if ((defined $params{stored_password}) && ($params{stored_password} =~ m/^\{PBKDF2\} ([0-9a-f]+) :/x)) {
28
    $salt = (split m{:}, Encode::encode('utf-8', $1), 2)[0];
29

  
30
  } else {
31
    my @login  = map { ord } split m{}, Encode::encode('utf-8', $params{login});
32
    my @random = map { int(rand(256)) } (0..16);
33

  
34
    $salt      = join '', map { sprintf '%02x', $_ } @login, @random;
35
  }
36

  
37
  my $hashed = "{PBKDF2}${salt}:" . join('', map { sprintf '%02x', ord } split m{}, PBKDF2::Tiny::derive('SHA-256', $salt, Encode::encode('utf-8', $params{password})));
38

  
39
  return $hashed;
40
}
8 41

  
9 42
sub hash {
10 43
  my ($class, %params) = @_;
11 44

  
12
  $params{algorithm} ||= 'SHA256S';
45
  $params{algorithm} ||= 'PBKDF2';
13 46

  
14 47
  my $salt = $params{algorithm} =~ m/S$/ ? $params{login} : '';
15 48

  
......
25 58
  } elsif ($params{algorithm} eq 'CRYPT') {
26 59
    return '{CRYPT}' . crypt($params{password}, substr($params{login}, 0, 2));
27 60

  
61
  } elsif ($params{algorithm} =~ m/^PBKDF2/) {
62
    return $class->hash_pkkdf2(password => $params{password}, stored_password => $params{stored_password});
63

  
28 64
  } else {
29 65
    croak 'Unsupported hash algorithm ' . $params{algorithm};
30 66
  }

Auch abrufbar als: Unified diff