Go Back   DaemonForums > Miscellaneous > Guides

Guides All Guides and HOWTO's.

Thread Tools Display Modes
Prev Previous Post   Next Post Next
  #1   (View Single Post)  
Old 10th February 2014
Carpetsmoker's Avatar
Carpetsmoker Carpetsmoker is offline
Real Name: Martin
Old man from scene 24
Join Date: Apr 2008
Location: Dutchman living in the UK
Posts: 2,198
Default Generate passwords from the commandline

I needed to generate a random password from a shell script, I figured that this was solved long ago, so I turned to teh interwebz to quickly copy/paste a working solution.
Inspecting the first few links that turned up, I noticed many of the proposed solutions are dubious at best.

The date ain’t random, buddy
The most obviously wrong are:

$ date +%s | sha256sum | base64 | head -c32
$ date | md5sum
$ ping -c 1 yahoo.com | md5 | head -c8
To paraphrase a quote from holy scripture The Hitchhikers guide to the Galaxy: “This is obviously some strange usage of the word ‘random’ that I hadn’t previously been aware of”.

Both SHA256 & MD5 also output in hex, so that would limit the total amount of characters to just 16, instead of 92.

tr means translate characters
Most of the other commands suffer from a dubious usage of tr(1).

tr(1) works on characters, not byte streams, /dev/urandom outputs a byte stream, not characters.
If your locale is set to (extended) ASCII or a variant thereof (ISO-8859-1, Windows-1252) this is more or less okay, since every byte is a character or escape code.

However, with UTF-8 or another multibyte character sets, it gets more complicated. Not every random byte stream is a valid set of UTF-8 characters, the chances of a random byte stream also being a valid UTF-8 character stream is quite small.

Yet, it seems to work on Linux with GNU tr. Why? Here’s a clue:

$ echo 'I løv€ π' | tr '[:lower:]' '[:upper:]' 
I LøV€ π

$ echo 'I løv€ π' | tr øπ€ X
We would expect the ø and π to be uppercased, but they’re not, and the ø, π, and € getting replaced by 2 or 3 X’s?

The astute reader will have recognized what this means, GNU tr doesn’t handle multibyte characters, and always assumes an ASCII character set, which is somewhat disappointing, since it’s 2014, not 1974.

FreeBSD, for example, does this correctly, it also gives an error message on invalid UTF-8 sequences:

$ echo 'I løv€ π' | tr '[:lower:]' '[:upper:]'

$ echo 'I løv€ π' | tr øπ€ X
I lXvX X

$ head -c5 /dev/urandom | tr X Y
tr: Illegal byte sequence

$ setenv LC_CTYPE C

$ head -c5 /dev/urandom | tr X Y
The moral here is: byte streams are not character streams, don’t use ’em as such. It may work for now, but whenever someone adds multibyte support to GNU tr, your command will fail. It’s 2014, always assume multibyte by default.

Other problems
While I’m whining anyway…

$ openssl rand -base64 8 | md5 | head -c8
Using openssl rand is a good idea, but piping it to md5 isn’t. base64 gives me 64 characters, md5 gives me 16, making the password a lot easier to brute force. Also, 8 characters is too short, use at least 15.

$ curl -s http://sensiblepassword.com/?harder=1
Getting a random from the internet is spectacularly stupid & naive. Someone now knows:
  • A password you are using for some service or site
  • Unique personal details about you (IP address, browser/environment info)
I can now cross-reference the info with other data collected about you. For example, you once posted to a mailing list, your IP address is in the mail’s header, so we now have a password, name, and an email address.
I hope you can finish the scenario from here…

Just don’t do this. Ever. Randomly banging on the keyboard is a lot better.

Good solutions
$ head -c100 /dev/urandom | strings -n1 | tr -d '[:space:]' | head -c15
$ openssl rand -base64 15
$ gpg2 --armor --gen-random 1 15
The first solution could be considered slightly better, since it includes more characters (92 instead of 64). It also doesn’t require external tools (although openssl is almost always available these days).

  • A byte streams is not the same thing as a character stream
  • Use strings(1) to convert a byte stream to a character stream
  • Don’t use the hex output of a hashing algorithm (SHA256, MD5)
  • Don’t trust copy/paste solutions from the internet; always think for yourself
  • BSD > GNU
UNIX was not designed to stop you from doing stupid things, because that would also stop you from doing clever things.
Reply With Quote

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Generating passwords with jot(1) J65nko Guides 9 29th August 2014 01:03 PM
Security LinkedIn passwords in circulation J65nko News 1 8th June 2012 04:49 AM
Experts: We're stuck with passwords – and maybe they're best J65nko News 1 17th January 2012 03:08 AM
Passwords zhorik OpenBSD General 5 14th January 2011 12:51 AM
Generate xorg.conf.new and black screen aleunix OpenBSD Packages and Ports 2 4th June 2008 10:49 AM

All times are GMT. The time now is 09:32 PM.

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Content copyright © 2007-2010, the authors
Daemon image copyright ©1988, Marshall Kirk McKusick