It seems reasonable, but I don't know all the possible attack vectors. Bytes::Random::Secure would provide strings that are based on a CSPRNG using the random_string_from function, but then you would have to do additional work to assure they contain the minimum requirement of upper/lower case, etc.
If nothing else exists, it might be worthwhile to create a module that does what you want, but bases it on a CSPRNG.
Update: This should generate ten passwords of length 8, consisting of a minimum of two lower-case ASCII letters, and two upper-case ASCII letters, with the balance consisting of a mix of other random characters (including alpha) from those available on a standard EN-US keyboard.
use Bytes::Random::Secure; use List::Util 'shuffle'; use constant CSPRNG => Bytes::Random::Secure->new( NonBlocking => 1 ); sub uppers { return CSPRNG->string_from( join( '', 'A'..'Z' ), shift // 2 ); } sub lowers { return CSPRNG->string_from( join( '', 'a'..'z' ), shift // 2 ); } sub mixed { return CSPRNG->string_from( join( '', 'A'..'Z', 'a'..'z', '0'..'9', '!@#$%^&*()_+{}|[]\<>?,./: +;"\'' ), shift // 4 ); } sub gen_pass { my $uc = uppers(); my $lc = lowers(); my $mix = mixed(); return join( '', shuffle( split //, "$uc$lc$mix" ) ); } for ( 1 .. 10 ) { print gen_pass(), "\n"; }
One possible shortcoming is that it does use List::Util::shuffle, which is a perfectly good implementation of the Fisher-Yates Shuffle, but it relies on the built-in rand again. So while the characters are generated by a CSPRNG, the ordering of those characters is handled by built-in rand. At least the characters themselves are being generated by the ISAAC algorithm, with a CSPRNG seeded using 256 bits of entropy supplied by a non-blocking call to Crypt::Random::Seed. CRS will use /dev/urandom in this case on Linux systems, or will make an API call on Windows systems.
If someone is really paranoid they might look for a shuffle that uses a pluggable random source so that it could be handed a CSPRNG to use in shuffling.
To be honest, it would probably be better to just forget about the minimum number of lowercase and uppercase characters, and make a single call to string_from. This will provide better entropy, as it doesn't constrain four of the digits to some narrower range, and it would eliminate the need to shuffle. Generate, then check against a dictionary, as well as looking for pathological cases like all the same digit, or sequential digits.
Dave
In reply to Re^3: String::MkPasswd still supported?
by davido
in thread String::MkPasswd still supported?
by Skeeve
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |