Cryptographically secure random string function

Objective: Find the most cryptographically secure random string generator. Use of alphabetic, numeric and, if possible, special characters in the string.

I've read here and elsewhere, but I still hear many different answers / opinions. Can people who are in the know and knowledgeable about security and cryptography here.

The following functions will be used to generate a random 8 character password as well as generate a random 128 character token.

Function 1:

/**
 * Used for generating a random string.
 *
 * @param int $_Length  The lengtyh of the random string.
 * @return string The random string.
 */
function gfRandomString($_Length) {
    $alphabet = "abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789";
    $pass = array(); //remember to declare $pass as an array
    $alphaLength = strlen($alphabet) - 1; //put the length -1 in cache
    for ($i = 0; $i < $_Length; $i++) {
        $n = rand(0, $alphaLength);
        $pass[] = $alphabet[$n];
    }
    return implode($pass); //turn the array into a string
}

      

Function 2:

The PHP.net docs say: crypto_strong : If passed to a function, this will contain a boolean value that determines if the algorithm was "cryptographically strong", such as secure for use with GPG, passwords, etc. TRUE if this happened, otherwise FALSE.

So is it server based? If I pass it once and itable to generate the crypto_strong string, can it always? Or I will need to check every time and create a loop until it generates the crypto_strong line.

/**
 * Used for generating a random string.
 *
 * @param int $_Length  The length of bits.
 * @return string The random string.
 */
function gfSecureString($_Length) {
    $Str = bin2hex(openssl_random_pseudo_bytes($_Length));
    return $Str; 
}

      

I welcome any suggestions for improving cryptographic strength.

+3


source to share


2 answers


So, you want to safely generate random strings in PHP . Neither of the two functions in the question will give you what you want, but the solution rand()

is the worst of the two. rand()

is unsafe
but bin2hex(openssl_random_pseudo_bytes())

limits your output character set.

In addition, it openssl_random_pseudo_bytes()

can be unreliable
in extreme conditions or exotic settings.

From what I understand, crypto_strong

will only be set to false

if RAND_pseudo_bytes()

unable to return any data. If OpenSSL is not seeded when it is called, it will silently return weak (and possibly predictable) pseudo-random bytes. You have no way, from PHP, to determine if this is random.

How to create secure random strings today

If you need a solution that has received substantial review for PHP 5.x, use RandomLib .

$factory = new RandomLib\Factory;
$generator = $factory->getMediumStrengthGenerator();
$randomPassword = $generator->generateString(20, $alphabet);

      



Alternative solutions

If you don't want to use RandomLib (even if, purely, because you want alternatives), you can also use random_int()

when PHP 7 comes out. If you can't wait to see this point, check out the random_compat project .

If you are using the cryptography library, libsodium , you can generate random numbers like this:

/**
 * Depends on the PECL extension libsodium
 * 
 * @link https://stackoverflow.com/a/31498051/2224584
 * 
 * @param int $length How long should the string be?
 * @param string $alphabet Contains all of the allowed characters
 * 
 * @return string
 */
function sodium_random_str($length, $alphabet = 'abcdefghijklmnopqrstuvwxyz')
{
    $buf = '';
    $alphabetSize = strlen($alphabet);
    for ($i = 0; $i < $length; ++$i) {
        $buf .= $alphabet[\Sodium\randombytes_uniform($alphabetSize)];
    }
    return $buf;
}

      

See this answer for example the code that uses random_int()

. I would rather not duplicate the effort to update the code in the future if the need arises.

+5


source


openssl_random_pseudo_bytes

has a pretty good chance of being a cryptographically secure generator, and of rand

course it isn't. However, it will only return binary data, which you return in hex. Hexadecimals are not enough to generate a password string. None of the features include the special characters that you think.



Thus, none of the code snippets suits your purpose.

+2


source







All Articles