0

Assume you want to generate a safe, random password with at least 8 characters in PHP, containing at least one uppercase, lowercase, number and special character.

I've read through some answers, basically all of them refer to here, this is why I choose RandomLib.

Unfortunately it doesn't seem to be possible to pass the "rules" to the generator.

My solution now is:

    $factory = new \RandomLib\Factory;
    $generator = $factory->getLowStrengthGenerator();
    $nums = $generator->generateString(random_int(1, 5), '0123456789');
    $capsStr = $generator->generateString(random_int(1, 6 - strlen($nums)), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
    $lowerStr = $generator->generateString(random_int(1, 7 - strlen($nums) - strlen($capsStr)), 'abcdefghijklmnopqrstuvwxyz');
    $special = $generator->generateString(random_int(1, 8 - strlen($nums) - strlen($capsStr) - strlen($lowerStr)), '+-!$%&#*_.;:<>' );
    $password = str_shuffle($nums . $capsStr . $lowerStr . $special);
    var_dump($password);

But I have a feeling this is inefficient and could be done faster. I get a "wallclock" execution time of around 0.025 Seconds on average. Furthermore I'm adding the "unsafe" random_int method, which I tried to prevent by using RandomLib

Is there a safer/faster way to achieve this?

NoLoHo
  • 76
  • 8
  • 1
    You solution is a poor one security-wise. 20% of the time it will generate a password with 5 digits and only a single upper case, lower case, and special character. And then you finish by using `str_shuffle` which doesn't use a secure RNG. Also, you are fundamentally misunderstanding the nature of secure passwords. If you are *generating* a password the only consideration should be entropy. Requiring 1 digit, 1 upper case, etc. from a generated password is just a form of obfuscation or "security through obscurity". – President James K. Polk Feb 23 '22 at 14:01
  • 1
    You would vastly improve security and simplicity by making a single call to `generateString(8, '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+-!$%*_.;:<>')`. The resulting password would have about 50 bits of entropy, good rather than spectacular but much more than the average password on the internet. – President James K. Polk Feb 23 '22 at 14:12
  • @PresidentJamesK.Polk Thank you for your input! Those requirements are imposed by the environment I'm implementing for, I didn't mean to imply they would make the password safer in any way. I'd love to just use `generateString()` like this, but it won't guarantee at least one each required character is contained. – NoLoHo Feb 23 '22 at 14:20
  • 1
    The requirements actually reduce the security of the password, but if they are requirements then so be it. It would still be simpler and cleaner to generate the password as per my comment in a loop and then check if it has the correct characteristics. I'm not going to compute the expected number of iterations but my gut feeling is that it is less than 2. – President James K. Polk Feb 23 '22 at 14:27
  • Related: https://stackoverflow.com/questions/4570980/generating-a-random-code-in-php/64472183#64472183 – Peter O. Feb 23 '22 at 18:21

0 Answers0