Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Re: What's the idea of different salts in crypt()?

by oneiros (Scribe)
on Sep 20, 2001 at 10:36 UTC ( #113536=note: print w/replies, xml ) Need Help??

in reply to What's the idea of different salts in crypt()?

Right. Knowing the salt is half the battle in cracking the password.

In addition to the suggestions of our fellow monks, I can add two more points.

Use a random salt and store the password in such a way where it will be extremely difficult for someone to obtain. Such as a configuration file only readable by the application itself. Some example code follows:

use strict; my $pass; $| = 1; print "password: "; chomp($pass = <STDIN>); print crypt_pass($pass), "\n"; exit; sub crypt_pass { my $p = shift; return unless $p; my $salt = chr(65+rand(27)).chr(65+rand(27)); return crypt($p, $salt); }

Another thing you can do is use the first two characters of the password as the salt, then strip those two characters off before you store it.

use strict; my $pass; $| = 1; print "password: "; chomp($pass = <STDIN>); print crypt_pass($pass), "\n"; exit; sub crypt_pass { my $p = shift; return unless $p; crypt($p, $p) =~ /..(.*)/; my $cpass = $1; return $cpass; }

Replies are listed 'Best First'.
Re: Re: What's the idea of different salts in crypt()?
by derby (Abbot) on Sep 20, 2001 at 16:59 UTC

    I agree with you about the need for random salt but not about "knowing it is half the battle." You always know the salt - it's right there out in the semi-open. It's always going to be the first two characters of the stored "hashed" value (I hate to call it an encrypted value because the value is normally the output of a crypto hash algrorithm).

    Consider the code for checking passwords:

    $pwd = (getpwuid($<))[1]; system "stty -echo"; print "Password: "; chomp($word = <STDIN>); print "\n"; system "stty echo"; if (crypt($word, $pwd) ne $pwd) { die "Sorry...\n"; } else { print "ok\n"; }
    The whole purpose of the salt is to slow down an attacker from comparing a list of pre-generated hashes against the target hash. Instead of needing to pre-compute one "hashed" value for each plaintext password, an attacker needs to precompute 16384 "hashed" values for each plaintext password (2^7 * 2^7). That kinda pales today but was pretty big when the crypt function was first developed - the computational power to pre-compute that many passwords times the number of plaintext password you suspect (dictionary) was pretty high. Not so much today which is why we have things like shadow passwords, other core password functions besides crypt and every sysad wanting you to pick a password that would not show up in a dictionary.


Re: Re: What's the idea of different salts in crypt()?
by blakem (Monsignor) on Sep 20, 2001 at 11:03 UTC
    I've seen people use the password as the salt before, but I have some hesitations about it. This seems to defeat the two arguments I've heard for salts.

    • Same plaintext yields different ciphertext.
      Obviously if the salt is determined by the plaintext, this idea flys out the window.
    • Greatly expands the ciphertext dictionary needed to check for common passwords.
      If the cracker figures out that your salts are based on the plaintext, the dictionary needed is exactly the same size as if there were no salts used at all.
    Of course, I've never quite gotten the concept of salts anyway.... They seem like a poorly thought out concept left over from the 70s. Use one of the modules mentioned above instead.


      It think you're confusing when to apply the advice to use the whole password. You don't use the plaintext password to create a salt when encrypting the password. You give the crypt function the whole encrypted password, salt and hashed password together as appears in the file, as the salt when authenticating a freshly entered plaintext password. This allows the crypt function to pull out as many bytes for the salt as the native crypt uses, whether that be the two for DES or some longer value. The rest is generally simply discarded by the crypt function. This way, you can write password authentication code which will work so long as the algortihm being used for authentication is the same as the one used for password creation and the two use the same interface. There's no need this way for the application to know beforehand how many bytes need to be given for the salt.

      That being said, let me repeat that when generating the salt, the plaintext password should play absolutely no role.

        The code I was commenting on does exactly that... it uses the plaintext password when generating the salt. In effect it is doing something like:
        my ($salt) = ($plaintextpassword =~ /^(..)/);
        Take a look at the last example in the node I replied to.


Log In?

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

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2023-03-22 06:23 GMT
Find Nodes?
    Voting Booth?
    Which type of climate do you prefer to live in?

    Results (60 votes). Check out past polls.