#! perl -wl

# Hashes a password from standard input using crypt(3), with key
# stretching.

# Copyright 2021 Ken Takusagawa

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

print STDERR "Type password and press ENTER:";
$plain=<STDIN>;
chomp$plain;

# create random salt
open RANDOM,"/dev/urandom" or die;
binmode(RANDOM);
@chars=("a".."z","A".."Z","0".."9",".","/");
die unless @chars==64;
for(0..15){
    $random=ord(getc RANDOM);
    die if$random<0;
    die if$random>255;
    $nonzero++ if $random;
    $salt.=$chars[$random & 63];
}

# sanity check that at least one non-zero byte was read from RANDOM
die unless $nonzero;

$type=6;
$rounds=300000;
$full='$'.$type."\$rounds=$rounds\$".$salt;
$hash=crypt $plain,$full;
print$hash;
