in reply to Is this use of crypt() appropriate?

Aside from the packet sniffing attack, what you are doing is very vulnerable to a dictionary attack.

You could mitigate this risk significantly by using a random salt instead of the constant "01".

Basically, if anyone finds out that the salt is "01", they only have to make one pass to encrypt every word in a dictionary and guess passwords. Randomize the salt, and they have to make a lot more passes.

One way to do that:

my @chars=(a..z,A..Z,0..9,'.','/'); my $salt= $chars[rand(@chars)] . $chars[rand(@chars)];
Update: Another option would be to use Crypt::PasswdMD5, which has the same basic interface as good old crypt, but it supposed to be more resistant to dictionary attacks. (YMMV, I'm not a cryptographer)

Replies are listed 'Best First'.
(ichimunki) Re x 2: crypt
by ichimunki (Priest) on Nov 08, 2001 at 03:44 UTC
    With the understanding that no non-core modules can be used we probably cannot get by with anything but crypt(), so the suggestion to add a random salt is a good one (although don't forget to store it in the database!).

    If going with a non-core module, I'd rather see that the password itself isn't even put in the cookie, maybe the MD5 or SHA1 hash, but even then to what end? We may as well use a semi-random or other mostly unique key in our cookie and prevent an attacker from having any clue how the passwords are stored in the database. That way we limit cracks to sniffing and to bad password selections on the part of users.

    And to prevent cracking, I'd suggest a limit to the number of tries a user gets-- although this brings up a DOS problem, which under the circumstances is likely to be a less invasive "crack" than unauthorized access to the system.

    {Just my additional two cents on this}
      ichimunki++

      That is the right idea. Rather than constantly passing the password back and forth, generate a random session ID when the user has successfully logged in. I suggest your session manager also tie a session to the IP it originally was started from, and that sessions be expired pretty quickly after some inactivity (when the user hasn't sent a request for, say, 30 minutes - though your specific application may make longer idle delays necessary).
Re: Re: crypt
by Aighearach (Initiate) on Nov 08, 2001 at 05:59 UTC
    Or if you don't like extra (read: temporary) vars, the canonical:

    my $crypt = crypt( $password, join( '', ('.', '/', 0..9, 'A'..'Z', 'a' +..'z')[rand 64, rand 64] ) );

    --
    Snazzy tagline here
Re: Re: crypt
by Anonymous Monk on Nov 08, 2001 at 02:25 UTC
    I'd use

    $enc_password = crypt($plain_password, $plain_password);

    But this method has the problem that abcdefghi will result the same as abcdefghij or any password beginning with the same 8 characters.
    You could use the first and the last character as salt to avoid this problem (the salt is cutted to two characters anyway).

    colli
      I'm not clear on why you would do this. Once the "bad guy" figures out what you've done:
      open(DICT,"/usr/dict/words"); while(<DICT>) { chomp; my $guess=crypt($_,$_); # insert some LWP code here to attack # the web page if ($it_worked) { print "$user: crypted password is $guess\n"; } } close DICT;
      On the other hand, if you randomize the salt, the loop above becomes an inner loop. Then the "bad guy" has to add an outer loop that runs up to 64*64 times.