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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.