File Coverage

blib/lib/Crypt/PostgreSQL.pm
Criterion Covered Total %
statement 49 52 94.2
branch 3 6 50.0
condition n/a
subroutine 14 14 100.0
pod 2 2 100.0
total 68 74 91.8


line stmt bran cond sub pod time code
1             # ABSTRACT: generate PostgreSQl password hashes
2             =head1 NAME
3             Crypt::PostgreSQL - Module for generating encrypted password for PostgreSQL
4              
5              
6             =head1 VERSION
7              
8             version 0.02
9              
10             =cut
11              
12 1     1   139242 use strict;
  1         3  
  1         39  
13 1     1   5 use warnings;
  1         7  
  1         76  
14             package Crypt::PostgreSQL;
15             $Crypt::PostgreSQL::VERSION = '0.02';
16             BEGIN {
17 1     1   7 use Exporter ();
  1         3  
  1         45  
18 1     1   6 use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         144  
19 1     1   16 @ISA = qw (Exporter);
20 1         6 @EXPORT = qw ();
21 1         2 @EXPORT_OK = qw ();
22 1         43 %EXPORT_TAGS = ();
23             }
24              
25 1     1   7 use Carp;
  1         2  
  1         102  
26 1     1   604 use Crypt::URandom;
  1         8010  
  1         60  
27 1     1   593 use Crypt::KeyDerivation qw(pbkdf2);
  1         6142  
  1         82  
28 1     1   572 use Crypt::Mac::HMAC qw(hmac hmac_b64);
  1         1606  
  1         79  
29 1     1   605 use Crypt::Digest::SHA256 qw(sha256_b64);
  1         2482  
  1         77  
30 1     1   611 use MIME::Base64;
  1         968  
  1         79  
31 1     1   7 use Digest::MD5 qw(md5_hex);
  1         2  
  1         353  
32              
33             =head1 SYNOPSIS
34              
35             use Crypt::PostgreSQL;
36              
37             print Crypt::PostgreSQL::encrypt_md5('my password', 'myuser');
38              
39             my $scram_hash = Crypt::PostgreSQL::encrypt_scram('my password');
40             my DBI;
41             my $dbh = DBI->connect("dbi:Pg:dbname=...", '', '', {AutoCommit => 0});
42             $dbh->do(q{
43             ALTER USER my_user SET ENCRYPTION PASSWORD '$scram_hash';
44             });
45              
46              
47             =head1 DESCRIPTION
48              
49             This module is for generating password suitable to generate password hashes in PostgreSQL format,
50             using one of the two encrypted formats: scram_sha_256 and md5
51              
52              
53             =head2 encrypt_md5
54              
55             The 1st argument is the password to encrypted
56              
57             The 2th argument is the postgresgl user name
58              
59             The function returns hash string suitable to use with ALTER USER SQL command.
60              
61             =cut
62              
63             sub encrypt_md5 {
64 1     1 1 174155 my($password, $user) = @_;
65 1 50       3 if(!length $user){
66 0         0 croak 'The 2nd parameter with the user is missing!';
67             }
68 1         11 return 'md5'.md5_hex($password.$user);
69             }
70              
71             =head2 encrypt_scram
72              
73             The 1st argument is the password to encrypted
74              
75             The 2nd argument, can define salt (use only for test!)
76              
77             The function returns hash string suitalbe to use with ALTER USER SQL command.
78              
79             =cut
80              
81             sub encrypt_scram {
82 1     1 1 5 my($password, $salt) = @_;
83 1 50       6 if(!defined $salt){
    50          
84 0         0 $salt = Crypt::URandom::urandom(16);
85             }elsif(length($salt) != 16){
86 0         0 croak 'The salt length must be 16!';
87             }
88 1         1 my $iterations = 4096;
89 1         9656 my $digest_key = pbkdf2($password, $salt, $iterations, 'SHA256', 32);
90 1         9 my $client_key = hmac('SHA256', $digest_key ,'Client Key');
91 1         5 my $b64_client_key = sha256_b64($client_key);
92 1         11 my $b64_server_key = hmac_b64('SHA256', $digest_key, 'Server Key');
93 1         4 my $b64_salt = encode_base64($salt, '');
94 1         6 return "SCRAM-SHA-256\$$iterations:$b64_salt\$$b64_client_key:$b64_server_key";
95             }
96              
97              
98             =head1 BUGS
99              
100             Please let the author know if any are caught
101              
102             =head1 AUTHOR
103              
104             Guido Brugnara
105             gdo@leader.it
106              
107              
108             =head1 COPYRIGHT
109              
110             This program is free software; you can redistribute
111             it and/or modify it under the same terms as Perl itself.
112              
113             The full text of the license can be found in the
114             LICENSE file included with this module.
115              
116              
117             =head1 SEE ALSO
118              
119             =over
120              
121             =item L
122              
123             PostgreSQL documentation: 20.5. Password Authentication
124              
125             =item L
126              
127             Blog article: PostgreSQL SCRAM-SHA-256 authentication with credits ...
128              
129             =back
130              
131             =cut
132              
133             1;