line |
stmt |
bran |
cond |
sub |
pod |
time |
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. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=cut |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
package Crypt::Eksblowfish::Bcrypt; |
36
|
|
|
|
|
|
|
|
37
|
3
|
|
|
3
|
|
90635
|
{ use 5.006; } |
|
3
|
|
|
|
|
13
|
|
|
3
|
|
|
|
|
145
|
|
38
|
3
|
|
|
3
|
|
19
|
use warnings; |
|
3
|
|
|
|
|
12
|
|
|
3
|
|
|
|
|
126
|
|
39
|
3
|
|
|
3
|
|
42
|
use strict; |
|
3
|
|
|
|
|
13
|
|
|
3
|
|
|
|
|
113
|
|
40
|
|
|
|
|
|
|
|
41
|
3
|
|
|
3
|
|
19
|
use Carp qw(croak); |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
348
|
|
42
|
3
|
|
|
3
|
|
2751
|
use Crypt::Eksblowfish 0.005; |
|
3
|
|
|
|
|
68
|
|
|
3
|
|
|
|
|
113
|
|
43
|
3
|
|
|
3
|
|
3495
|
use MIME::Base64 2.21 qw(encode_base64 decode_base64); |
|
3
|
|
|
|
|
3033
|
|
|
3
|
|
|
|
|
375
|
|
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
our $VERSION = "0.009"; |
46
|
|
|
|
|
|
|
|
47
|
3
|
|
|
3
|
|
21
|
use parent "Exporter"; |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
20
|
|
48
|
|
|
|
|
|
|
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 |
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 |
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 |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
Exactly sixteen octets of salt. |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=back |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
=cut |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
sub bcrypt_hash($$) { |
82
|
70
|
|
|
70
|
1
|
150
|
my($settings, $password) = @_; |
83
|
70
|
100
|
100
|
|
|
461
|
$password .= "\0" if $settings->{key_nul} || $password eq ""; |
84
|
70
|
|
|
|
|
1080402
|
my $cipher = Crypt::Eksblowfish->new($settings->{cost}, |
85
|
|
|
|
|
|
|
$settings->{salt}, substr($password, 0, 72)); |
86
|
210
|
|
|
|
|
1176
|
my $hash = join("", map { |
87
|
70
|
|
|
|
|
480
|
my $blk = $_; |
88
|
210
|
|
|
|
|
578
|
for(my $i = 64; $i--; ) { |
89
|
13440
|
|
|
|
|
49005
|
$blk = $cipher->encrypt($blk); |
90
|
|
|
|
|
|
|
} |
91
|
210
|
|
|
|
|
769
|
$blk; |
92
|
|
|
|
|
|
|
} qw(OrpheanB eholderS cryDoubt)); |
93
|
70
|
|
|
|
|
214
|
chop $hash; |
94
|
70
|
|
|
|
|
772
|
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
|
92
|
|
|
92
|
1
|
11305
|
my($octets) = @_; |
106
|
92
|
|
|
|
|
457
|
my $text = encode_base64($octets, ""); |
107
|
92
|
|
|
|
|
267
|
$text =~ tr#A-Za-z0-9+/=#./A-Za-z0-9#d; |
108
|
92
|
|
|
|
|
690
|
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
|
92
|
|
|
92
|
1
|
171
|
my($text) = @_; |
120
|
92
|
50
|
|
|
|
546
|
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
|
92
|
|
|
|
|
204
|
$text =~ tr#./A-Za-z0-9#A-Za-z0-9+/#; |
125
|
92
|
|
|
|
|
508
|
$text .= "=" x (3 - (length($text) + 3) % 4); |
126
|
92
|
|
|
|
|
1188
|
return decode_base64($text); |
127
|
|
|
|
|
|
|
} |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=item bcrypt(PASSWORD, SETTINGS) |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
This is a version of C (see L) 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. |
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 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
|
68
|
|
|
68
|
1
|
44868
|
my($password, $settings) = @_; |
155
|
68
|
50
|
|
|
|
462
|
croak "bad bcrypt settings" |
156
|
|
|
|
|
|
|
unless $settings =~ m#\A\$2(a?)\$([0-9]{2})\$ |
157
|
|
|
|
|
|
|
([./A-Za-z0-9]{22})#x; |
158
|
68
|
|
|
|
|
242
|
my($key_nul, $cost, $salt_base64) = ($1, $2, $3); |
159
|
68
|
|
|
|
|
194
|
my $hash = bcrypt_hash({ |
160
|
|
|
|
|
|
|
key_nul => $key_nul, |
161
|
|
|
|
|
|
|
cost => $cost, |
162
|
|
|
|
|
|
|
salt => de_base64($salt_base64), |
163
|
|
|
|
|
|
|
}, $password); |
164
|
68
|
|
|
|
|
487
|
return "\$2${key_nul}\$${cost}\$${salt_base64}".en_base64($hash); |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=back |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
=head1 SEE ALSO |
170
|
|
|
|
|
|
|
|
171
|
|
|
|
|
|
|
L, |
172
|
|
|
|
|
|
|
L |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=head1 AUTHOR |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
Andrew Main (Zefram) |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
=head1 COPYRIGHT |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 |
181
|
|
|
|
|
|
|
Andrew Main (Zefram) |
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; |