Created
February 19, 2014 08:45
-
-
Save mschmitt/9088238 to your computer and use it in GitHub Desktop.
Helper for generating and checking password hashes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/perl -w | |
use diagnostics; | |
use strict; | |
use POSIX qw(setsid); | |
use Crypt::Passwd::XS; | |
use Tk; | |
# Fork off. | |
if (1){ | |
fork() && exit; | |
#print STDERR "\nForked: PID $$\n"; | |
chdir "/"; | |
open STDIN, "</dev/null"; | |
open STDERR, ">/dev/null"; | |
open STDOUT, ">/dev/null"; | |
} | |
# Some global variables used later | |
my @salt_chars = ('.', '/', 0..9, 'A'..'Z', 'a'..'z'); | |
my $pw2hash_radiobutton = 'DES'; | |
my $pw2hash_radiobutton_previous = ' '; | |
my $pw2hash_input_show = '*'; | |
my $pw2hash_input_previous = ''; | |
my $match_hash_pw_input_show = '*'; | |
# UI element definition | |
my $mw = MainWindow->new(); | |
$mw->title('Shadow Mangler'); | |
$mw->minsize(400,0); | |
my $pw2hash_frame = $mw->Frame( | |
); | |
my $match_hash_frame = $mw->Frame( | |
); | |
my $pw2hash_label = $pw2hash_frame->Label( | |
-text => 'Convert password to hash:' | |
); | |
my $pw2hash_input = $pw2hash_frame->Entry( | |
-show => '*' | |
); | |
my $pw2hash_reveal_button = $pw2hash_frame->Checkbutton( | |
-text => 'Reveal', | |
-command => \&pw2hash_input_show_toggle | |
); | |
my $pw2hash_des_button = $pw2hash_frame->Radiobutton( | |
-text => 'DES', | |
-value => 'DES', | |
-variable => \$pw2hash_radiobutton, | |
-command => \&pw2hash_do_hash | |
); | |
my $pw2hash_md5_button = $pw2hash_frame->Radiobutton( | |
-text => 'MD5', | |
-value => 'MD5', | |
-variable => \$pw2hash_radiobutton, | |
-command => \&pw2hash_do_hash | |
); | |
my $pw2hash_sha512_button = $pw2hash_frame->Radiobutton( | |
-text => 'SHA-512', | |
-value => 'SHA-512', | |
-variable => \$pw2hash_radiobutton, | |
-command => \&pw2hash_do_hash | |
); | |
my $pw2hash_output = $pw2hash_frame->Entry( | |
-takefocus => 0, | |
-state => 'readonly' | |
); | |
my $match_hash_label = $match_hash_frame->Label( | |
-text => 'Match password and existing hash:' | |
); | |
my $match_hash_pw_input_label = $match_hash_frame->Label( | |
-text => 'Password:' | |
); | |
my $match_hash_pw_input = $match_hash_frame->Entry( | |
-show => '*' | |
); | |
my $match_hash_pw_input_reveal_button = $match_hash_frame->Checkbutton( | |
-text => 'Reveal', | |
-command => \&match_hash_pw_input_show_toggle | |
); | |
my $match_hash_hash_input_label = $match_hash_frame->Label( | |
-text => 'Hash:' | |
); | |
my $match_hash_hash_input = $match_hash_frame->Entry( | |
); | |
my $match_hash_indicator = $match_hash_frame->Label( | |
-text => 'Not matching', | |
-foreground => 'red' | |
); | |
# UI element positioning - TODO: Arrange more neatly. LOL. | |
# Internal frames for each application use case | |
$pw2hash_frame->pack(-side => 'top', -fill => 'both', -padx => 10, -pady => 10); | |
$match_hash_frame->pack(-side => 'top', -fill => 'both', -padx => 10, -pady => 10); | |
$pw2hash_label->pack; | |
$pw2hash_input->pack(-fill => 'x'); | |
$pw2hash_reveal_button->pack; | |
$pw2hash_des_button->pack; | |
$pw2hash_md5_button->pack; | |
$pw2hash_sha512_button->pack; | |
$pw2hash_output->pack(-fill => 'x'); | |
$match_hash_label->pack; | |
$match_hash_pw_input_label->pack; | |
$match_hash_pw_input->pack(-fill => 'x'); | |
$match_hash_pw_input_reveal_button->pack; | |
$match_hash_hash_input_label->pack; | |
$match_hash_hash_input->pack(-fill => 'x'); | |
$match_hash_indicator->pack; | |
# Automatic actions on input fields | |
foreach ('<KeyRelease>', '<ButtonRelease>', '<<Paste>>'){ | |
$pw2hash_input->bind($_ => \&pw2hash_do_hash); | |
$match_hash_pw_input->bind($_ => \&match_hash_do_match); | |
$match_hash_hash_input->bind($_ => \&match_hash_do_match); | |
} | |
MainLoop; # It's pretty much downhill from here. | |
sub pw2hash_input_show_toggle { | |
if ($pw2hash_input_show){ | |
$pw2hash_input->configure(-show => ''); | |
$pw2hash_input_show = ''; | |
}else{ | |
$pw2hash_input->configure(-show => '*'); | |
$pw2hash_input_show = '*'; | |
} | |
1; | |
} | |
sub pw2hash_do_hash { | |
# Only recalculate if input or radio button have changed | |
if ( ($pw2hash_radiobutton ne $pw2hash_radiobutton_previous) or | |
($pw2hash_input->get() ne $pw2hash_input_previous) ){ | |
$pw2hash_radiobutton_previous = $pw2hash_radiobutton; | |
$pw2hash_input_previous = $pw2hash_input->get(); | |
if ($pw2hash_radiobutton eq 'DES'){ | |
pw2hash_des(); | |
}elsif($pw2hash_radiobutton eq 'MD5'){ | |
pw2hash_md5(); | |
}elsif($pw2hash_radiobutton eq 'SHA-512'){ | |
pw2hash_sha512(); | |
} | |
} | |
1; | |
} | |
sub pw2hash_des { | |
my $salt; | |
for(1..2) { | |
$salt .= $salt_chars[int(rand(scalar(@salt_chars)))]; | |
} | |
my $encrypted_pass = Crypt::Passwd::XS::crypt($pw2hash_input->get(), $salt); | |
$pw2hash_output->configure(-text => $encrypted_pass); | |
1; | |
} | |
sub pw2hash_md5 { | |
my $salt = '$1$'; | |
for(1..8) { | |
$salt .= $salt_chars[int(rand(scalar(@salt_chars)))]; | |
} | |
my $encrypted_pass = Crypt::Passwd::XS::crypt($pw2hash_input->get(), $salt); | |
$pw2hash_output->configure(-text => $encrypted_pass); | |
1; | |
} | |
sub pw2hash_sha512 { | |
my $salt = '$6$'; | |
for(1..8) { | |
$salt .= $salt_chars[int(rand(scalar(@salt_chars)))]; | |
} | |
my $encrypted_pass = Crypt::Passwd::XS::crypt($pw2hash_input->get(), $salt); | |
$pw2hash_output->configure(-text => $encrypted_pass); | |
1; | |
} | |
sub match_hash_pw_input_show_toggle { | |
if ($match_hash_pw_input_show){ | |
$match_hash_pw_input->configure(-show => ''); | |
$match_hash_pw_input_show = ''; | |
}else{ | |
$match_hash_pw_input->configure(-show => '*'); | |
$match_hash_pw_input_show = '*'; | |
} | |
1; | |
} | |
sub match_hash_do_match { | |
my ($input_pass, $input_hash) = ($match_hash_pw_input->get(), $match_hash_hash_input->get()); | |
if ($input_pass and $input_hash){ | |
if (Crypt::Passwd::XS::crypt($input_pass, $input_hash) eq $input_hash){ | |
$match_hash_indicator->configure( | |
-foreground => 'green', | |
-text => 'Matching' | |
); | |
}else{ | |
$match_hash_indicator->configure( | |
-foreground => 'red', | |
-text => 'Not Matching' | |
); | |
} | |
}else{ | |
$match_hash_indicator->configure( | |
-foreground => 'red', | |
-text => 'Not Matching' | |
); | |
} | |
1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment