Simple password generator in Bash
December 11, 2007 | 22:58Every time you need to create a password, you have to choose it well, that is you should use something which is very difficult to be guessed by anyone. In other words the password must be strong.
This article will tell when a password is considered a good one and how to automatically produce one with a simple bash script.
Three simple rules to obtain a strong password are:
- make it long;
- make it composed by characters which are choosen from a very big pool (alfanumeric ciphers is not enough!);
- don’t include anything related to you (birthdate, son’s name, etc.) or better: to anything.
The perfect password, then, is a long word made of strange characters choosen randomly. What’s better then, of an automatic random password generator?
Here is a very simple (but unsecure, don’t use it!) bash script that will generate a random word of the given length (default is 6 characters):
#!/bin/bash
charspool=('a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p'
'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' '0' '1' '2' '3' '4' '5' '6' '7'
'8' '9' '0' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O'
'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '!' '£' '$' '%' '&' '=' '.' ',' ';' ':' '-' '_');
len=${#charspool[*]}
if [ $# -lt 1 ]; then
num=6;
else
num=$1;
fi
echo -n "password: "
for c in $(seq $num); do
echo -n ${charspool[$((RANDOM % len))]}
done
echo
This code, that is very similar to the base64 algorithm, just extracts a number from $RANDOM bash variable and uses it to find the appropriate character in a fixed array (the pool).
In this case however, another problem emerges: how random is a number generated by a computer?
Well, in short the answer is that what we obtain from a computer is not a random (in fact it’s called pseudo-random) number but the event in which the same number is extracted by the modern pseudo-number generator (Bash’s one included) it’s stastically very rare.
The latter cannot be demonstrated without a full test of the generator. On the other hand, a quick proof that every generated number is just pseudo-random consists in seeding the generator with always the same seed:
$ RANDOM=1
$ for i in {1..10}; do echo -n "$RANDOM "; done; echo ""
16838 5758 10113 17515 31051 5627 23010 7419 16212 4086
This sequence is quite random, but if we reassign the value of 1 to $RANDOM we will obtain the same one again:
$ RANDOM=1
$ for i in {1..10}; do echo -n "$RANDOM "; done; echo;
16838 5758 10113 17515 31051 5627 23010 7419 16212 4086
In addition, when using a pseudo-random number generator for creating sensitive data such as passwords, we need to guarantee that nobody can recover the entire random sequence by knowing a part of it. It’s easily demonstrable that Bash pseudo-random number generator fails this property by allowing anyone to identify its internal state and thus all the precedent and subsequent random values by knowing a sequence of at least three values.
Moreover, every generator has a fixed length of these sequences after which it will repeat again from the begin; this length determines the quality of a pseudorandom number generator: the longer, the better.
A way to patch this problem is to re-seed the generator every tot numbers, each time with a different value; here is an example of how you do:
$ RANDOM=$(date '+%s')
Anyway, if you want to achieve a stronger randomness you should use /dev/urandom which comes directly from the kernel. Here is the previous script adapted to th
#!/bin/bash
charspool=('a' 'b' 'c' 'd' 'e' 'f' 'g' 'h' 'i' 'j' 'k' 'l' 'm' 'n' 'o' 'p'
'q' 'r' 's' 't' 'u' 'v' 'w' 'x' 'y' 'z' '0' '1' '2' '3' '4' '5' '6' '7'
'8' '9' '0' 'A' 'B' 'C' 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' 'N' 'O'
'P' 'Q' 'R' 'S' 'T' 'U' 'V' 'W' 'X' 'Y' 'Z' '!' '£' '$' '%' '&' '=' '.' ',' ';' ':' '-' '_');
len=${#charspool[*]}
if [ $# -lt 1 ]; then
num=6;
else
num=$1;
fi
randomnumbers=$(head -c $num /dev/urandom | od -t u1 | awk '{for (i = 2; i <= NF; i++) print $i}')
echo -n "password: "
for c in $randomnumbers; do
echo -n ${charspool[$((c % len))]}
done
echo
References:
- Password Guide on Security Focus;
- random generation on linux












TheBonsai | April 7, 2009 | 6:45
Avoid the seq-tool if possible:
mla | July 20, 2009 | 11:20
And here’s a one-liner version
Same concept as yours except it’s using uuencode so it doesn’t include as much punctuation. So somewhat less secure.
function mkpw() { head /dev/urandom | uuencode -m – | sed -n 2p | cut -c1-${1:-8}; }
Колко сигурни за паролите, които ползваме? – BulTux | March 13, 2010 | 20:47
[...] Скриптът е взет от: My. Debian [...]