News:

Who uses forums anymore?

Main Menu

blag

Started by Sidoh, March 04, 2010, 06:23:45 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

iago

Heh. Salt doesn't have to be strongly random. In fact, salt can be equal to the username, the date, incremental, etc. The only trick with salt is to make sure it's distinct for every user.

Sidoh

Quote from: iago on March 16, 2011, 08:56:15 AM
Heh. Salt doesn't have to be strongly random. In fact, salt can be equal to the username, the date, incremental, etc. The only trick with salt is to make sure it's distinct for every user.


Yes, of course, but I was more interested in the answer to the question "is that a good random salt?"

iago

Yes, that's a decent way of generating a random value, and it's as good a salt as any! :)

Sidoh


iago

WWiD for what? For a salt value, just pick some kinda-random letters or sequential values. Like I said, as long as no two users have the same salt, there's no bad salting.

Sidoh

Quote from: iago on March 16, 2011, 06:19:56 PM
WWiD for what? For a salt value, just pick some kinda-random letters or sequential values. Like I said, as long as no two users have the same salt, there's no bad salting.

Hehe... yeah.  I probably shouldn't have used the word "salt" anywhere.  It was misleading

Say you want to generate a random password or something.  How would you do it?  I'd probably just use the line I provided above (or something close to it).

iago

Honestly, I don't know what the right answer is. That's why I didn't say in the blog the "right" way.

I think as long as you have a reasonable source of entropy, and a decent RNG, you're okay.

btw, if you're using php, don't use rand(), use mt_rand(). It's better. Also, don't use srand() (I see that you aren't, but you might be using it elsewhere). PHP seeds itself.

iago

Btw, here's how smf generates it:

function generateValidationCode()
{
  global $modSettings;

  $request = db_query('
    SELECT RAND()', __FILE__, __LINE__);

  list ($dbRand) = mysql_fetch_row($request);
  mysql_free_result($request);

  return substr(preg_replace('/\W/', '', sha1(microtime() . mt_rand() . $dbRand . $modSettings['rand_seed'])), 0, 10);
}


It uses microtime, mt_rand(), a random value from mysql, and a random seed that's stored in the settings. That'd be extremely difficult to predict.

iago

#23
Here's Wordpress:
function wp_rand( $min = 0, $max = 0 ) {
 global $rnd_value;

 // Reset $rnd_value after 14 uses
 // 32(md5) + 40(sha1) + 40(sha1) / 8 = 14 random numbers from $rnd_value
 if ( strlen($rnd_value) < 8 ) {
   if ( defined( 'WP_SETUP_CONFIG' ) )
     static $seed = '';
   else
     $seed = get_transient('random_seed');
   $rnd_value = md5( uniqid(microtime() . mt_rand(), true ) . $seed );
   $rnd_value .= sha1($rnd_value);
   $rnd_value .= sha1($rnd_value . $seed);
   $seed = md5($seed . $rnd_value);
   if ( ! defined( 'WP_SETUP_CONFIG' ) )
     set_transient('random_seed', $seed);
 }

 // Take the first 8 digits for our value
 $value = substr($rnd_value, 0, 8);

 // Strip the first eight, leaving the remainder for the next call to wp_rand().
 $rnd_value = substr($rnd_value, 8);

 $value = abs(hexdec($value));

 // Reduce the value to be within the min - max range
 // 4294967295 = 0xffffffff = max random number
 if ( $max != 0 )
   $value = $min + (($max - $min + 1) * ($value / (4294967295 + 1)));

 return abs(intval($value));
}


I find you can tell when people don't know what they're doing by seeing that they throw a bunch of stuff in there that doesn't add any strength (for example, using both md5 and sha1, calling sha1 multiple times on the same value, etc).

In any case, the key to their security is, in part, that they save $seed across subsequent calls, so every call to the function uses a seed generated by the previous call.

iago

And finally, here's Mediawiki:
  static function randomPassword() {
    global $wgMinimalPasswordLength;
    $pwchars = 'ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz';
    $l = strlen( $pwchars ) - 1;

    $pwlength = max( 7, $wgMinimalPasswordLength );
    $digit = mt_rand( 0, $pwlength - 1 );
    $np = '';
    for ( $i = 0; $i < $pwlength; $i++ ) {
      $np .= $i == $digit ? chr( mt_rand( 48, 57 ) ) : $pwchars{ mt_rand( 0, $l ) };
    }
    return $np;
  }


It's much simpler, but I'm a little concerned about the strength. Unless a min password length is set, it does 7 characters - 6 letters and a number. That's 197,706,096,640 combinations. So yeah, that's pretty damn big, but not nearly as big as it ought to be. Why in the hell did they put a number in the middle and default it to 7 characters?

Losers. :)

Sidoh

Quote from: iago on March 17, 2011, 12:16:38 AM
Honestly, I don't know what the right answer is. That's why I didn't say in the blog the "right" way.

I think as long as you have a reasonable source of entropy, and a decent RNG, you're okay.

btw, if you're using php, don't use rand(), use mt_rand(). It's better. Also, don't use srand() (I see that you aren't, but you might be using it elsewhere). PHP seeds itself.


Aha, I recall reading that in the docs for rand().  I guess I forgot. :)

Yep, I know about srand.

Heh, mediawiki's is pretty terrible.  People are weird.

iago

I'm actually impressed at the effort they went to to intentionally weaken it. :)

Sidoh

Quote from: iago on March 17, 2011, 08:58:09 AM
I'm actually impressed at the effort they went to to intentionally weaken it. :)

Yeah.  Very confusing.

I missed this before:

Quote from: iago on March 17, 2011, 12:36:01 AM
Unless a min password length is set, it does 7 characters - 6 letters and a number. That's 197,706,096,640 combinations.

Since the position of the digit isn't fixed, it's actually:

52^6 * 10 * 7 = 1,383,942,676,480

iago

Good call, I forgot the 7.

iago

Quote from: Sidoh on March 15, 2011, 06:15:51 PM
I liked the last two posts on your blag.  They were cool.  I especially liked the Taco Bell programming bit.  I've never used xargs in that way, but I definitely will be doing so in the future.

This seems like a solid (ish) way to generate random salts in PHP. Thoughts?


$salt = md5(rand() . microtime())


It seems to me that this is about as good as it gets.  Some of the things people come up with are a lot more convoluted than this, which puzzles me.
So, it turns out that rand() and mt_rand() are both seeded by 32-bit values that are somewhat known. And microtime() is actually one of those values. That means that, in reality, due to PHP's crappy random number generator, that may not be especially secure. :)

(I'm going to post a blog on Tuesday (give or take) about this.