1#!/usr/bin/perl -w 2use strict; 3use Getopt::Long qw(:config no_ignore_case); 4use Pod::Usage; 5use Digest::SHA; 6use MIME::Base64; 7use Math::Random::Secure qw(irand); 8 9my %opts; 10GetOptions(\%opts, 11 qw[ help|?! man! f|format=s l|len=i s|salt=s S|Salt=s z|saltlen:i ] 12) or pod2usage(2); 13pod2usage(1) if $opts{help}; 14pod2usage(-verbose => 2) if $opts{man}; 15 16my $len = 256; 17if (exists $opts{l}) { 18 my @length = (224, 256, 384, 512); 19 if (grep {$_ eq $opts{l}} @length) { 20 $len = $opts{l}; 21 } else { 22 print "Bad length\n"; 23 exit(1); 24 } 25} 26 27sub fmt_base64 { 28 return encode_base64(shift, '')."\n"; 29} 30 31sub fmt_hex { 32 return unpack('H*', shift)."\n"; 33} 34 35sub fmt_bin { 36 return shift; 37} 38 39my $fmt = \&{'fmt_base64'}; 40if (exists $opts{f}) { 41 my %format = ('m' => \&{'fmt_base64'}, 'base64' => \&{'fmt_base64'}, 42 'x' => \&{'fmt_hex'}, 'hex' => \&{'fmt_hex'}, 43 'b' => \&{'fmt_bin'}, 'bin' => \&{'fmt_bin'}); 44 $fmt = $format{$opts{f}}; 45 if (!defined $fmt) { 46 print "Bad format\n"; 47 exit(1); 48 } 49} 50 51my $password = $ARGV[0]; 52if (!defined $password) { 53 print "Missing password\n"; 54 exit(1); 55} 56 57my $salt = $opts{s}; 58if (exists $opts{S}) { 59 if (defined $salt) { 60 print "Redundant salt\n"; 61 exit(1); 62 } 63 $salt = pack('H*', $opts{S}); 64} elsif (!defined $salt and exists $opts{z}) { 65 my $ssiz = $opts{z}; 66 if ($ssiz == 0) { 67 $ssiz = 8; 68 } elsif ($ssiz < 0) { 69 print "Bad salt length\n"; 70 exit(1); 71 } 72 while ($ssiz >= 4) { 73 $salt .= pack('N', irand()); 74 $ssiz -= 4; 75 } 76 $salt .= substr(pack('N', irand()), 1, $ssiz) if ($ssiz > 0); 77} 78 79my $ctx = Digest::SHA->new($len); 80$ctx->add($password); 81$ctx->add($salt) if (defined $salt); 82my $dig = $ctx->digest; 83$dig .= $salt if (defined $salt); 84 85print &$fmt($dig); 86 87__END__ 88 89=head1 NAME 90 91ssha2passwd - Generate a SHA2 hashed password 92 93=head1 DESCRIPTION 94 95Hash the given password into a SHA2 digest with optional salt. 96 97=head1 SYNOPSIS 98 99 ssha2passwd [options] <password> 100 101=head1 OPTIONS 102 103=over 104 105=item B<-f> or B<-format> <format> 106 107Format options: 108 109=over 110 111=item B<m> or B<base64> : base64 encoded (default) 112 113=item B<x> or B<hex> : hexadecimal string 114 115=item B<b> or B<bin> : binary string 116 117=back 118 119=item B<-l> or B<-length> <length> 120 121Hash algorithm bit length (224, 256, 384, or 512 | default: 256). 122 123=item B<-s> or B<-salt> <string> 124 125=item B<-S> or B<-Salt> <hexadecimal string> 126 127Salt string appended to password and hashed. The resultant digest then 128has the salt string appended. 129 130=item B<-z> or B<-saltlen> [<length>] 131 132Byte length of random salt appended to password and hashed, if no salt 133string is explicitly given (0 is default, default: 8). 134 135=item B<-?> or B<-help> 136 137Print a brief help message. 138 139=item B<-man> 140 141Print the manual page. 142 143=back 144=cut 145