Ok so, I've spent days looking at codes from here and other places and I just keep piecing parts together. This script works for me, and I'm still vetting security vulnerabilities, however I have tried to create it with due diligance. I'm not a perl genius and a bit rusty with regexp.
The purpose of this script will be used as an embedded key for chatroom purposes, I will most likely use the original crypt to branch off a second key, hence the extra step and obfuscation in case someone starts pulling apart the layers of generated printed pages. I don't want to have the same key used for login stored in database as the one embedded but for obvious reasons they need to same root pass. I may have overshot cleaning characters in too many places but I figured why not, in case I make this a separate file.
use Digest::SHA qw(hmac_sha256_hex);
sub passCrypt {
chomp(my $userin=$_[0]); # first passed var is username
chomp(my $passin=$_[1]); # second passed var is plaintext password
$userin = substr $userin, 0, 24; # protect from DoS attacks by limiting length of input
$passin = substr $passin, 0, 64;
$passin =~ tr/\\\?\/\<\>/XPZQJ/; # clean password replacing \ ? / < > with safe chars
$passin =~ s/0x[0-9a-fA-F]//g; # clean password from hex 0x0 - 0xF
$userin =~ s/[^\w]//g; # clean username from any non-word characters (a-z A-Z 0-9 _)
$userin =~ s/[_]//g; # clean username from the _ (for salt)
$userin = lc($userin); # all lowercase username
my $salt = substr($userin, 1, 1) . substr($userin, -2, 1); # make salt from first and last of username
my $clnpass = crypt($passin,$salt); # use basic crypt to prevent plain text password being utilized beyond this point
$clnpass = substr $clnpass, 2; # strip salt from beginning of pass
$clnpass =~ tr/\/\\\!\@\#\$\%\^\&\*\(\)\[\]\{\}\|\?\=\+\-\_\<\>\:\;\"\'\`\,\./1234567890123456789012345678901/; # make pass filename safe (replacement to keep consistent length)
$clnpass =~ tr/abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ/WXYZwxcd123efghFGHIJij4ABlmnopqNOPQRrstuCDEKL567MSkyzTUVa890/; # added obfuscation
$clnpass = reverse($clnpass); # more obfuscation
my $cryptpass = hmac_sha256_hex($clnpass, chr(0x0b) x 32); # final crypt with sha256
return $cryptpass;
}
I'm putting this up here in case someone else doing searches runs into similar questions as I have, and hoping for lots of suggestions of improvement. Is there a better way to provide decent password hashing in a perl cgi script? I first looked into Crypt::Eksblowfish::Bcrypt but my host doesn't have that package. Thanks in advance.
Edit: It was clarified to me that all I'm doing is hashing so I replaced said text.