Cody Pendant has asked for the wisdom of the Perl Monks concerning the following question:

Can someone explain the "salt" part of a crypt to me?

It appears to be a way to get extra randomness into the encryption, as far as my limited understanding of these things goes.

But if you're checking that crypt($password) matches the crypt($password) you've saved previously, and you use a different salt, it won't match, surely?

Signed, Easily Confused.
--

($_='jjjuuusssttt annootthheer pppeeerrrlll haaaccckkeer')=~y/a-z//s;print;

Replies are listed 'Best First'.
Re: Tales from the crypt()
by Zaxo (Archbishop) on May 24, 2002 at 23:05 UTC

    crypted password digests have the salt tacked onto the front in plain text, like this:

    $ perl -e'print crypt("glaummer", "es"), $/' esWBuiGT4AQcA $
    All you need to do is capture the salt with my $salt = substr $digest, 0, 2; , then crypt away.

    Update: Fixed typo in code (s/crupt/crypt/) ++rob_au for the spot.

    After Compline,
    Zaxo

Re: Tales from the crypt()
by DigitalKitty (Parson) on May 25, 2002 at 01:04 UTC
    Hi.

    The salt is similar to an identifier. I've heard specific algorithms use specfic salts. I could be mistaken, but I believe perl uses either 3DES or DES. The first two characters comprise the salt used when the crypt function was called initially. When you perform some action that calls the crypt function ( such as login or su ), it extracts the first two characters ( the salt ), and attempts to 're-hash' your password with the following function:

    if (crypt( $data, $hashed_text) eq $hashed_text )
    // additional code here.

    Since you are hopefully using the same password, and since the crypt() function is using the same salt, it should create the same hashed string again. If these two conditions are true, they will match and..success!

    Sample run:
    #!/usr/bin/perl -w use strict; my $data = "Perlmonks!"; $data = crypt( $data, "hj" ); print $data, "\n"; #Results in... C:\perl>perl crypt_test.pl hjCQi34Qt4uGE C:\perl>

    As you can see, the salt ( "hj" ) can be found at the beginning of the string.
    If you wanted to incorporate this into an application, you could do something like this:

    #!/usr/bin/perl -w use strict; my $password; my $salt; print "Please enter password: "; chomp( $password = <STDIN> ); print "Enter two-char salt: "; chomp( $salt = <STDIN> ); $password = crypt( $password, $salt ); # Then to 'verify' the authenticity, use # the value of $password you obtained earlier. print "Please enter your password: "; chomp( my $guess = <STDIN> ); print "Imposter!" if( crypt($guess, $password) ne $password);

    I hope this helps,

    -Katie a.k.a. DigitalKitty
      I could be mistaken, but I believe perl uses either 3DES or DES.

      From 'perldoc -f crypt': Encrypts a string exactly like the crypt(3) function in the C library. So actually Perl depends on system library (aka libc on Unix systems) here. I've seen crypt to return MD5 hashes on some systems.

      --
      Ilya Martynov (http://martynov.org/)

Re: Tales from the crypt()
by derby (Abbot) on May 25, 2002 at 00:58 UTC
    Yes, you are right. Thats why the salt is part of the hashed password - so you can use the saved salt with the supplied password. Check out this node for more info on salt(s) and why it's used.

    -derby

Re: Tales from the crypt()
by DamnDirtyApe (Curate) on May 24, 2002 at 22:50 UTC
    But if you're checking that crypt($password) matches the crypt($password) you've saved previously, and you use a different salt, it won't match, surely?

    I don't know a lot about it either, but this seems to be correct.

    use strict ; my @n = qw( xx xy yx yy ) ; my @m = @n ; foreach my $outer ( @n ) { foreach my $inner ( @m ) { print crypt( 'perlmonk', $inner ) eq crypt( 'perlmonk', $outer + ) ? '1' : '0' ; } print "\n" ; }
    gives you this:
    1000 0100 0010 0001

    _______________
    D a m n D i r t y A p e
    Home Node | Email