The ideal password would be:
- Secure: Randomly drawn with equal probability from a sufficiently large set;
- Usable: Easy for a human being to memorize and input into their device.
These two goals are at odds, but that's a story for another day. For your question, then, you need to answer what components of your proposals are contributing to those two goals, and which are just superfluous. And looking at it:
/dev/urandom makes random choices with equal probability, and the number of bytes you read from
/dev/urandom puts bounds on the size of the set from which those random choices are made. So pulling enough bytes from
/dev/urandom will fulfill #1 on its own.
- The output of
/dev/urandom is random bytes that are hard for humans to memorize and input. So you need a method to convert those random bytes into a user-friendly alphanumeric string. The only real requirement for that method is that it produce a sufficient number of distinct outputs, and that any of those outputs is equally likely as all the others.
md5sum isn't contributing anything to security here. All it's really doing is converting the random bytes to a hexadecimal string, in a convoluted (but otherwise acceptable) way. That, coupled with the fact that MD5 is a broken hash function, is a big code smell.
- Drawing 8,192 random bytes to drop all those that aren't ASCII hexadecimal digits is a crassly inefficient way to produce a random hexadecimal string. It also has a non-zero probability of producing fewer than the 32 hex digits that you're aiming for. Why not just draw 16 random bytes and encode them to hex directly?
So a big simplification of your proposals is the command that Stephen beat me to:
% head -c16 /dev/urandom | xxd -p
One possible improvement, following my #2 from above, would be to use a more compact binary-to-ASCII encoding, like Base64 (with the trailing
= signs deleted):
% head -c16 /dev/urandom |base64 |tr -d '='
Next improvement: just make the passwords shorter so that people don't have to type as much. If you just draw 10 random bytes the passwords have 80 bits of entropy, which is much stronger than the passwords most real-life users choose.
% head -c10 /dev/urandom | base64 |tr -d '='
And another improvement, which helps only in the memorability front, would be to encode the random bytes as random passphrases, like in Diceware or the famous XKCD comic.
Note that my final recommendations—using 80 bits of entropy instead of 128—are, in strict numerical terms, less secure than what you started with proposing. But the key philosophical point here is that the design only needs to be secure enough, and as long as a reasonable target security level is met there's no gain from going beyond it. If anything, the longer passwords needed to achieve "greater" security are harder to use. But security at the cost of usability often comes at the cost of security.