File Coverage

blib/lib/Jifty/DBI/Filter/SaltHash.pm
Criterion Covered Total %
statement 26 27 96.3
branch 5 6 83.3
condition n/a
subroutine 7 7 100.0
pod 3 3 100.0
total 41 43 95.3


line stmt bran cond sub pod time code
1             package Jifty::DBI::Filter::SaltHash;
2              
3 1     1   5 use warnings;
  1         2  
  1         28  
4 1     1   5 use strict;
  1         1  
  1         30  
5              
6 1     1   3 use base qw|Jifty::DBI::Filter|;
  1         2  
  1         60  
7 1     1   3 use Digest::MD5 qw(md5_hex);
  1         2  
  1         220  
8              
9             =head1 NAME
10              
11             Jifty::DBI::Filter::SaltHash - salts and hashes a value before storing it
12              
13             =head1 DESCRIPTION
14              
15             This filter will generate a random 4-byte salt, and then MD5 the given
16             value with the salt appended to the value. It will store the hash and
17             the salt in the database, and return a data structure that contains
18             both on decode. The salt and hash are stored in hexadecimal in the
19             database, so that you can put them in a text field.
20              
21             This filter is intended for storing passwords in a database.
22              
23             =head2 encode
24              
25             Generate a random 4-byte salt, MD5 the value with the salt (encoded to
26             hexadecimal) appended to it, and store both in the database.
27              
28             =cut
29              
30             sub encode {
31 2     2 1 4 my $self = shift;
32 2         9 my $value_ref = $self->value_ref;
33              
34 2 100       22 return unless defined $$value_ref;
35              
36 1         3 my $salt = generate_salt();
37              
38 1         20 $$value_ref = md5_hex($$value_ref, $salt) . $salt;
39             }
40              
41             =head2 generate_salt
42              
43             Return a random 4-byte salt value, encoded as an 8-character hex
44             string.
45              
46             =cut
47              
48             sub generate_salt {
49 1     1 1 2 my $salt;
50 1         15 $salt .= unpack('H2',chr(int rand(255))) for(1..4);
51 1         3 return $salt;
52             }
53              
54             =head2 decode
55              
56             Return an arrayref of (hash, salt), both as hex strings.
57              
58             To test whether a provided value is the same one originally encoded,
59             use
60              
61             $hash eq md5_hex($value . $salt);
62              
63             =cut
64              
65             sub decode {
66 2     2 1 3 my $self = shift;
67 2         10 my $value_ref = $self->value_ref;
68              
69 2 100       17 return unless $$value_ref;
70              
71             # This should never happen, but just to be safe
72 1 50       4 unless(length($$value_ref) == (8 + 32)) {
73 0         0 $$value_ref = [undef, undef];
74             } else {
75 1         8 $$value_ref = [unpack("A32A8", $$value_ref)];
76             }
77              
78 1         5 return 1;
79             }
80              
81              
82              
83             =head1 SEE ALSO
84              
85             L, L
86              
87             =cut
88              
89             1;