OSEC

Neohapsis is currently accepting applications for employment. For more information, please visit our website www.neohapsis.com or email hr@neohapsis.com
 
From: rain forest puppy (rfpwiretrip.net)
Date: Wed Mar 06 2002 - 17:44:56 CST

  • Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]

    > i'm not familiar with /dev/random. Do you just cat it or what?

    read it like you would a binary file. So, in PHP:

    $fh=fopen("/dev/random","r");
    if($fh){
            $bytes=fread($fh, 16);
            fclose($fh);
    }
    if(!$fh || strlen($bytes)!=16){
            echo "Error reading (enough) random data";
            // puke
    }

    This ensures you get 16 bytes (128 bits). Since it is possible to exhaust
    your entropy pool, you don't want to get greedy in reading too many random
    characters....16 should be more than enough (it is equivalent to a MD5
    hash).

    Since $bytes is already random, you don't need to make it 'more random' by
    hashing it again. A MD5 hash gives you 128 random bits, which you already
    have. Thus you can save the CPU cycles. You can use a base64 or hex
    string of $bytes as the session ID (just make sure it doesn't collide with
    an already-existing ID).

    The good place to use hashing is when:
    A) you have less random bits than what the hash outputs, or
    B) you don't want the user to see the source data

    If it's purely random bytes, then you're good to go on both accounts.
    But let's say you only read 8 random bytes in from /dev/random....then you
    would want to md5 it because the result would be 16 random bytes--more
    than you started with (but brute forcing would only require finding the
    source 8 random bytes, and not all 16 of the MD5 hash).

    > $secret="128_bits_of_noise_here";
    > $random=a_random_element;
    > $sessid=MD5(microtime().$REMOTE_ADDR.$secret.$random);

    That would work. Slightly overkill, but fine. But if you have $random
    bits, then microtime and secret are not really needed. The $random +
    $REMOTE_ADDR should give you a good random hash, and $REMOTE_ADDR will
    hopefully keep it from colliding with an existing session ID (something
    you should always check anyways).

    > or are you talking about something more complex? And what about things like
    > XORing? Perhaps one could take the microtime, XOR each byte by the random
    > element, and then append that to the secret? is this the sort of process
    > you're talking about?

    Not really...XORing would just obfuscate things--it doesn't add any real
    security value, and it just needlessly makes things more complex and
    slower. There's no point xoring microtime with a random element#1 to get
    random element#2. If random element#1 is truly random, then you don't
    have to do anything else to it (and if you do, you risk having it lose
    it's randomness). If random element#1 is not truly random, then the XOR
    will not produce a truly random element#2 either. So save the cycles.

    Microtime() is good for about 20 bits of randomness (basically the
    unpredictable microsecond value). A keyboard-based password/secret would
    vary, but the guesstimate average is 3 bits per character. The
    REMOTE_ADDR is typically considered 'unknown', and thus random...so that's
    32 bits of randomness--however, since particular sections of internet
    address are not used, realistically it's more like 20-26 bits. Your goal
    should be to get at least 128 bits of randomness involved.

    So you can read something like /dev/random and get all 128 in one fell
    swoop, or you can cobble things like microtime and REMOTE_ADDR together in
    hopes to get enough source bits, and then hash it.

    Code wise, using /dev/random is cleaner and faster. On Win platforms,
    you'll have to dig into the MS crypto provider for a RNG.

    - rfp