| Filename | /usr/lib/x86_64-linux-gnu/perl5/5.20/Crypt/Eksblowfish/Bcrypt.pm |
| Statements | Executed 20 statements in 8.65ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 1 | 1 | 1 | 8.15ms | 9.72ms | Crypt::Eksblowfish::Bcrypt::BEGIN@42 |
| 1 | 1 | 1 | 21µs | 21µs | Crypt::Eksblowfish::Bcrypt::BEGIN@37 |
| 1 | 1 | 1 | 15µs | 49µs | Crypt::Eksblowfish::Bcrypt::BEGIN@43 |
| 1 | 1 | 1 | 10µs | 18µs | Crypt::Eksblowfish::Bcrypt::BEGIN@38 |
| 1 | 1 | 1 | 8µs | 33µs | Crypt::Eksblowfish::Bcrypt::BEGIN@41 |
| 1 | 1 | 1 | 7µs | 37µs | Crypt::Eksblowfish::Bcrypt::BEGIN@47 |
| 1 | 1 | 1 | 6µs | 17µs | Crypt::Eksblowfish::Bcrypt::BEGIN@39 |
| 0 | 0 | 0 | 0s | 0s | Crypt::Eksblowfish::Bcrypt::bcrypt |
| 0 | 0 | 0 | 0s | 0s | Crypt::Eksblowfish::Bcrypt::bcrypt_hash |
| 0 | 0 | 0 | 0s | 0s | Crypt::Eksblowfish::Bcrypt::de_base64 |
| 0 | 0 | 0 | 0s | 0s | Crypt::Eksblowfish::Bcrypt::en_base64 |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | =head1 NAME | ||||
| 2 | |||||
| 3 | Crypt::Eksblowfish::Bcrypt - Blowfish-based Unix crypt() password hash | ||||
| 4 | |||||
| 5 | =head1 SYNOPSIS | ||||
| 6 | |||||
| 7 | use Crypt::Eksblowfish::Bcrypt qw(bcrypt_hash); | ||||
| 8 | |||||
| 9 | $hash = bcrypt_hash({ | ||||
| 10 | key_nul => 1, | ||||
| 11 | cost => 8, | ||||
| 12 | salt => $salt, | ||||
| 13 | }, $password); | ||||
| 14 | |||||
| 15 | use Crypt::Eksblowfish::Bcrypt qw(en_base64 de_base64); | ||||
| 16 | |||||
| 17 | $text = en_base64($octets); | ||||
| 18 | $octets = de_base64($text); | ||||
| 19 | |||||
| 20 | use Crypt::Eksblowfish::Bcrypt qw(bcrypt); | ||||
| 21 | |||||
| 22 | $hashed_password = bcrypt($password, $settings); | ||||
| 23 | |||||
| 24 | =head1 DESCRIPTION | ||||
| 25 | |||||
| 26 | This module implements the Blowfish-based Unix crypt() password hashing | ||||
| 27 | algorithm, known as "bcrypt". This hash uses a variant of Blowfish, | ||||
| 28 | known as "Eksblowfish", modified to have particularly expensive key | ||||
| 29 | scheduling. Eksblowfish and bcrypt were devised by Niels Provos and | ||||
| 30 | David Mazieres for OpenBSD. The design is described in a paper at | ||||
| 31 | L<http://www.usenix.org/events/usenix99/provos.html>. | ||||
| 32 | |||||
| 33 | =cut | ||||
| 34 | |||||
| 35 | package Crypt::Eksblowfish::Bcrypt; | ||||
| 36 | |||||
| 37 | 3 | 51µs | 1 | 21µs | # spent 21µs within Crypt::Eksblowfish::Bcrypt::BEGIN@37 which was called:
# once (21µs+0s) by Koha::AuthUtils::BEGIN@21 at line 37 # spent 21µs making 1 call to Crypt::Eksblowfish::Bcrypt::BEGIN@37 |
| 38 | 2 | 23µs | 2 | 26µs | # spent 18µs (10+8) within Crypt::Eksblowfish::Bcrypt::BEGIN@38 which was called:
# once (10µs+8µs) by Koha::AuthUtils::BEGIN@21 at line 38 # spent 18µs making 1 call to Crypt::Eksblowfish::Bcrypt::BEGIN@38
# spent 8µs making 1 call to warnings::import |
| 39 | 2 | 26µs | 2 | 29µs | # spent 17µs (6+12) within Crypt::Eksblowfish::Bcrypt::BEGIN@39 which was called:
# once (6µs+12µs) by Koha::AuthUtils::BEGIN@21 at line 39 # spent 17µs making 1 call to Crypt::Eksblowfish::Bcrypt::BEGIN@39
# spent 12µs making 1 call to strict::import |
| 40 | |||||
| 41 | 2 | 27µs | 2 | 58µs | # spent 33µs (8+25) within Crypt::Eksblowfish::Bcrypt::BEGIN@41 which was called:
# once (8µs+25µs) by Koha::AuthUtils::BEGIN@21 at line 41 # spent 33µs making 1 call to Crypt::Eksblowfish::Bcrypt::BEGIN@41
# spent 25µs making 1 call to Exporter::import |
| 42 | 3 | 8.03ms | 2 | 9.73ms | # spent 9.72ms (8.15+1.56) within Crypt::Eksblowfish::Bcrypt::BEGIN@42 which was called:
# once (8.15ms+1.56ms) by Koha::AuthUtils::BEGIN@21 at line 42 # spent 9.72ms making 1 call to Crypt::Eksblowfish::Bcrypt::BEGIN@42
# spent 9µs making 1 call to version::_VERSION |
| 43 | 3 | 48µs | 3 | 83µs | # spent 49µs (15+34) within Crypt::Eksblowfish::Bcrypt::BEGIN@43 which was called:
# once (15µs+34µs) by Koha::AuthUtils::BEGIN@21 at line 43 # spent 49µs making 1 call to Crypt::Eksblowfish::Bcrypt::BEGIN@43
# spent 28µs making 1 call to Exporter::import
# spent 6µs making 1 call to version::_VERSION |
| 44 | |||||
| 45 | 1 | 300ns | our $VERSION = "0.009"; | ||
| 46 | |||||
| 47 | 2 | 436µs | 2 | 68µs | # spent 37µs (7+30) within Crypt::Eksblowfish::Bcrypt::BEGIN@47 which was called:
# once (7µs+30µs) by Koha::AuthUtils::BEGIN@21 at line 47 # spent 37µs making 1 call to Crypt::Eksblowfish::Bcrypt::BEGIN@47
# spent 30µs making 1 call to parent::import |
| 48 | 1 | 800ns | our @EXPORT_OK = qw(bcrypt_hash en_base64 de_base64 bcrypt); | ||
| 49 | |||||
| 50 | =head1 FUNCTIONS | ||||
| 51 | |||||
| 52 | =over | ||||
| 53 | |||||
| 54 | =item bcrypt_hash(SETTINGS, PASSWORD) | ||||
| 55 | |||||
| 56 | Hashes PASSWORD according to the supplied SETTINGS, and returns the | ||||
| 57 | 23-octet hash. SETTINGS must be a reference to a hash, with these keys: | ||||
| 58 | |||||
| 59 | =over | ||||
| 60 | |||||
| 61 | =item B<key_nul> | ||||
| 62 | |||||
| 63 | Truth value: whether to append a NUL to the password before using it as a key. | ||||
| 64 | The algorithm as originally devised does not do this, but it was later | ||||
| 65 | modified to do it. The version that does append NUL is to be preferred; | ||||
| 66 | not doing so is supported only for backward compatibility. | ||||
| 67 | |||||
| 68 | =item B<cost> | ||||
| 69 | |||||
| 70 | Non-negative integer controlling the cost of the hash function. | ||||
| 71 | The number of operations is proportional to 2^cost. | ||||
| 72 | |||||
| 73 | =item B<salt> | ||||
| 74 | |||||
| 75 | Exactly sixteen octets of salt. | ||||
| 76 | |||||
| 77 | =back | ||||
| 78 | |||||
| 79 | =cut | ||||
| 80 | |||||
| 81 | sub bcrypt_hash($$) { | ||||
| 82 | my($settings, $password) = @_; | ||||
| 83 | $password .= "\0" if $settings->{key_nul} || $password eq ""; | ||||
| 84 | my $cipher = Crypt::Eksblowfish->new($settings->{cost}, | ||||
| 85 | $settings->{salt}, substr($password, 0, 72)); | ||||
| 86 | my $hash = join("", map { | ||||
| 87 | my $blk = $_; | ||||
| 88 | for(my $i = 64; $i--; ) { | ||||
| 89 | $blk = $cipher->encrypt($blk); | ||||
| 90 | } | ||||
| 91 | $blk; | ||||
| 92 | } qw(OrpheanB eholderS cryDoubt)); | ||||
| 93 | chop $hash; | ||||
| 94 | return $hash; | ||||
| 95 | } | ||||
| 96 | |||||
| 97 | =item en_base64(BYTES) | ||||
| 98 | |||||
| 99 | Encodes the octet string textually using the form of base 64 that is | ||||
| 100 | conventionally used with bcrypt. | ||||
| 101 | |||||
| 102 | =cut | ||||
| 103 | |||||
| 104 | sub en_base64($) { | ||||
| 105 | my($octets) = @_; | ||||
| 106 | my $text = encode_base64($octets, ""); | ||||
| 107 | $text =~ tr#A-Za-z0-9+/=#./A-Za-z0-9#d; | ||||
| 108 | return $text; | ||||
| 109 | } | ||||
| 110 | |||||
| 111 | =item de_base64(TEXT) | ||||
| 112 | |||||
| 113 | Decodes an octet string that was textually encoded using the form of | ||||
| 114 | base 64 that is conventionally used with bcrypt. | ||||
| 115 | |||||
| 116 | =cut | ||||
| 117 | |||||
| 118 | sub de_base64($) { | ||||
| 119 | my($text) = @_; | ||||
| 120 | croak "bad base64 encoding" | ||||
| 121 | unless $text =~ m#\A(?>(?:[./A-Za-z0-9]{4})*) | ||||
| 122 | (?:|[./A-Za-z0-9]{2}[.CGKOSWaeimquy26]| | ||||
| 123 | [./A-Za-z0-9][.Oeu])\z#x; | ||||
| 124 | $text =~ tr#./A-Za-z0-9#A-Za-z0-9+/#; | ||||
| 125 | $text .= "=" x (3 - (length($text) + 3) % 4); | ||||
| 126 | return decode_base64($text); | ||||
| 127 | } | ||||
| 128 | |||||
| 129 | =item bcrypt(PASSWORD, SETTINGS) | ||||
| 130 | |||||
| 131 | This is a version of C<crypt> (see L<perlfunc/crypt>) that implements the | ||||
| 132 | bcrypt algorithm. It does not implement any other hashing algorithms, | ||||
| 133 | so if others are desired then it necessary to examine the algorithm | ||||
| 134 | prefix in SETTINGS and dispatch between more than one version of C<crypt>. | ||||
| 135 | |||||
| 136 | SETTINGS must be a string which encodes the algorithm parameters, | ||||
| 137 | including salt. It must begin with "$2", optional "a", "$", two | ||||
| 138 | digits, "$", and 22 base 64 digits. The rest of the string is ignored. | ||||
| 139 | The presence of the optional "a" means that a NUL is to be appended | ||||
| 140 | to the password before it is used as a key. The two digits set the | ||||
| 141 | cost parameter. The 22 base 64 digits encode the salt. The function | ||||
| 142 | will C<die> if SETTINGS does not have this format. | ||||
| 143 | |||||
| 144 | The PASSWORD is hashed according to the SETTINGS. The value returned | ||||
| 145 | is a string which encodes the algorithm parameters and the hash: the | ||||
| 146 | parameters are in the same format required in SETTINGS, and the hash is | ||||
| 147 | appended in the form of 31 base 64 digits. This result is suitable to | ||||
| 148 | be used as a SETTINGS string for input to this function: the hash part | ||||
| 149 | of the string is ignored on input. | ||||
| 150 | |||||
| 151 | =cut | ||||
| 152 | |||||
| 153 | sub bcrypt($$) { | ||||
| 154 | my($password, $settings) = @_; | ||||
| 155 | croak "bad bcrypt settings" | ||||
| 156 | unless $settings =~ m#\A\$2(a?)\$([0-9]{2})\$ | ||||
| 157 | ([./A-Za-z0-9]{22})#x; | ||||
| 158 | my($key_nul, $cost, $salt_base64) = ($1, $2, $3); | ||||
| 159 | my $hash = bcrypt_hash({ | ||||
| 160 | key_nul => $key_nul, | ||||
| 161 | cost => $cost, | ||||
| 162 | salt => de_base64($salt_base64), | ||||
| 163 | }, $password); | ||||
| 164 | return "\$2${key_nul}\$${cost}\$${salt_base64}".en_base64($hash); | ||||
| 165 | } | ||||
| 166 | |||||
| 167 | =back | ||||
| 168 | |||||
| 169 | =head1 SEE ALSO | ||||
| 170 | |||||
| 171 | L<Crypt::Eksblowfish>, | ||||
| 172 | L<http://www.usenix.org/events/usenix99/provos.html> | ||||
| 173 | |||||
| 174 | =head1 AUTHOR | ||||
| 175 | |||||
| 176 | Andrew Main (Zefram) <zefram@fysh.org> | ||||
| 177 | |||||
| 178 | =head1 COPYRIGHT | ||||
| 179 | |||||
| 180 | Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 | ||||
| 181 | Andrew Main (Zefram) <zefram@fysh.org> | ||||
| 182 | |||||
| 183 | =head1 LICENSE | ||||
| 184 | |||||
| 185 | This module is free software; you can redistribute it and/or modify it | ||||
| 186 | under the same terms as Perl itself. | ||||
| 187 | |||||
| 188 | =cut | ||||
| 189 | |||||
| 190 | 1 | 3µs | 1; |