Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling
 
PerlMonks  

Re: Ecrypting passwords

by kjd (Acolyte)
on Oct 07, 2003 at 01:11 UTC ( #297135=note: print w/replies, xml ) Need Help??


in reply to Ecrypting passwords

Here's two programs I had from a project using salted SHA1 passwords as above in hardburn's post. One hashes a given password, and the other compares a hashed password to plaintext, returning the result:
% ./sha1pass test {SSHA}06mQAx78jfQWriWZRKeC8r3UCcpF7QtdsJ967w== % ./cmpsha1pass {SSHA}06mQAx78jfQWriWZRKeC8r3UCcpF7QtdsJ967w== test debug: got b64salt: Re0LXbCfeu8= Original: {SSHA}06mQAx78jfQWriWZRKeC8r3UCcpF7QtdsJ967w== Computed: {SSHA}06mQAx78jfQWriWZRKeC8r3UCcpF7QtdsJ967w== Passwords match. % ./cmpsha1pass {SSHA}06mQAx78jfQWriWZRKeC8r3UCcpF7QtdsJ967w== badpass debug: got b64salt: Re0LXbCfeu8= Original: {SSHA}06mQAx78jfQWriWZRKeC8r3UCcpF7QtdsJ967w== Computed: {SSHA}feht7DIITMD3PyNONqnXnFAnNVJF7QtdsJ967w== Passwords do not match!
#!/usr/local/bin/perl -w # # sha1pass -- Ken Draper <robo at manipulate dot org> # # Generates an 8-byte-salted SHA1 password from a plaintext # input string. Salt goes at the end of the string. # # Password may be input as an argument on the command-line, # piped as standard input, or entered in reply to a non-echoed # prompt. # # $Id: sha1pass,v 1.2 2003/06/02 21:04:44 kjd Exp kjd $ # use 5.006; use strict; use warnings; use POSIX; use MIME::Base64; use Digest::SHA1; sub sprinkle ($); sub read_stdin_passwd (); sub input_is_a_tty (); sub user_response (); sub echo_off ($$); sub echo_on ($$); #======================================= # Main #======================================= my ($ctx, $pass, $hash, $salt); $pass = shift or do { $pass = read_stdin_passwd(); }; $ctx = Digest::SHA1->new; $salt = sprinkle(8); # get an 8-byte random salt $ctx->add($pass); $ctx->add($salt); $hash = '{SSHA}' . encode_base64($ctx->digest . $salt, ''); print "$hash\n"; #=============================================================== # FUNCTIONS #=============================================================== ## # sprinkle ( nbytes ) # # Returns nbytes bytes of randomness, using entropy device if present # sub sprinkle ($) { my $n = $_[0]; # how many random bytes my ($salt, $len, $entropy_file); my @entropy_files = qw(/dev/random /dev/urandom); my $have_entropy = 0; foreach $entropy_file (@entropy_files) { #warn "debug: sprinkle(): trying entropy file $entropy_file\n" +; if (open(RAND, $entropy_file)) { $have_entropy++; last; } else { next; } } if (!$have_entropy) { #warn "debug: sprinkle(): no entropy file, using rand()\n"; my @granules; for (my $i = 0; $i < $n; $i++) { $granules[$i] = rand 256; } $salt = pack('C8', @granules); } else { unless ( ($len = read(RAND, $salt, $n)) == $n) { warn "sprinkle(): got $len bytes of entropy for seed (need + $n)\n"; die "sprinkle(): last error was: $!\n"; } close(RAND) || do { warn "sprinkle(): Error closing entropy source: $!\n"; warn "sprinkle(): Attempting to continue normally...\n"; }; } #warn "debug: sprinkle(): b64salt: ", encode_base64($salt); return($salt); } ## # read_stdin_passwd -- Gets passwd from STDIN; no echo if input is a t +ty # sub read_stdin_passwd () { my ($t, $term_orig, $pass); if (input_is_a_tty) { $t = POSIX::Termios->new(); $t->getattr(); $term_orig = $t->getlflag(); echo_off(\$t, \$term_orig); $pass = user_response(); echo_on(\$t, \$term_orig); } else { $pass = <STDIN>; chomp($pass); } return($pass); } sub input_is_a_tty () { return -t STDIN && -t STDOUT } ## # user_response -- Prompts for a password until it gets one # sub user_response () { my ($ret, $pass); print STDERR "Password: "; while ($pass = <STDIN>) { chomp($pass); if (length($pass) > 0) { last; } else { print STDERR "\nPassword: "; } } print "\n"; return($pass); } ## # echo_off ( Termios obj ref , current terminal flags ref ) # # Disables terminal echo # sub echo_off ($$) { my ($t, $term_orig) = @_; my ($echo, $no_echo); $echo = (&POSIX::ECHO|&POSIX::ECHOK); $no_echo = $$term_orig; $no_echo &= ~$echo; $$t->setlflag($no_echo); $$t->setattr(0, &TCSANOW); } ## # echo_on ( Termios obj ref , original terminal flags ref ) # # Restores specified original terminal state # sub echo_on ($$) { my ($t, $term_orig) = @_; $$t->setlflag($$term_orig); $$t->setattr(0, &TCSANOW); } #!/usr/local/bin/perl -w # # Test script for sha1pass outputs # # Usage: cmpsha1pass <hashed password> <plaintext password> # use strict; use warnings; use MIME::Base64; use Digest::SHA1; my $hash = shift || usage(); # stored hashed password (incl. salt) my $pass = shift || usage(); # actual password for comparison my $binary_hash = decode_base64($hash); my $salt = substr($binary_hash, -8, 8); # extract salt warn "debug: got b64salt: ", encode_base64($salt); my $ctx = Digest::SHA1->new; $ctx->add($pass); $ctx->add($salt); my $cmp_hash = '{SSHA}' . encode_base64($ctx->digest . $salt, ''); print "Original: ", "$hash\n"; print "Computed: ", "$cmp_hash\n"; if ($hash eq $cmp_hash) { print "Passwords match.\n"; } else { print "Passwords do not match!\n"; } exit(0); sub usage { die "Usage: $0 <hashed password> <plaintext password>\n"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://297135]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2021-04-18 04:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?