LinuxQuestions.org
Help answer threads with 0 replies.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Software
User Name
Password
Linux - Software This forum is for Software issues.
Having a problem installing a new program? Want to know which application is best for the job? Post your question in this forum.

Notices



Reply
 
Search this Thread
Old 02-09-2010, 01:54 PM   #1
jojothedogboy
LQ Newbie
 
Registered: Jun 2008
Posts: 12

Rep: Reputation: 0
BASH Password Generator


Not sure if this goes here or under Security, however, I have hacked together some code from two different sources to make a password generator for FTP accounts.

Question: How will the "strength" of an eight character password generated by the following code compare to a human generated eight character password? Will they be equally as strong?

Is reading from /dev/urandom good/better/worse then just using RANDOM()? Will "salting" either result add more "strength"?

Password Generator:
Code:
#!/bin/bash
MATRIX="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz!@#$%&*?-_=+)(}{][><"
LENGTH="8"
while [ "${n:=1}" -le "$LENGTH" ]
do
        RealRand=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" ")
        PASS="$PASS${MATRIX:$(($RealRand%${#MATRIX})):1}"

        #         echo "$PASS"
        let n+=1
done
echo "$PASS"      # ==> Or, redirect to a file, as desired.
exit 0
Code Credits:

Code:
I added some code from HERE
dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" "

to THIS replacing the RANDOM call.
#!/bin/bash
# May need to be invoked with  #!/bin/bash2  on older machines.
#
#  Random password generator for Bash 2.x +
#+ by Antek Sawicki <tenox@tenox.tc>,
#+ who generously gave usage permission to the ABS Guide author.
#
# ==> Comments added by document author ==>
MATRIX="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
# ==> Password will consist of alphanumeric characters.
LENGTH="8"
# ==> May change 'LENGTH' for longer password.
while [ "${n:=1}" -le "$LENGTH" ]
# ==> Recall that := is "default substitution" operator.
# ==> So, if 'n' has not been initialized, set it to 1.
do
	PASS="$PASS${MATRIX:$(($RANDOM%${#MATRIX})):1}"
	# ==> Very clever, but tricky.
	# ==> Starting from the innermost nesting...
	# ==> ${#MATRIX} returns length of array MATRIX.
	# ==> $RANDOM%${#MATRIX} returns random number between 1
	# ==> and [length of MATRIX] - 1.
	# ==> ${MATRIX:$(($RANDOM%${#MATRIX})):1}
	# ==> returns expansion of MATRIX at random position, by length 1. 
	# ==> See {var:pos:len} parameter substitution in Chapter 9.
	# ==> and the associated examples.
	# ==> PASS=... simply pastes this result onto previous PASS (concatenation).
	# ==> To visualize this more clearly, uncomment the following line
	#                 echo "$PASS"
	# ==> to see PASS being built up,
	# ==> one character at a time, each iteration of the loop.
	let n+=1
	# ==> Increment 'n' for next pass.
done
echo "$PASS"      # ==> Or, redirect to a file, as desired.
exit 0
 
Old 02-09-2010, 02:19 PM   #2
irmin
Member
 
Registered: Jan 2010
Location: the universe
Distribution: Slackware (modified), Slackware64 (modified), openSuSE (modified)
Posts: 342

Rep: Reputation: 62
RANDOM will only create pseudo random numbers. So the same seed will lead to the same password. Thus you should either try to seed the random number generator before using it or stick to your version with /dev/urandom (which really creates random numbers).

I think that the strength of the passwords created this way will be much higher than human created passwords, because humans tend to use familiar patterns in their password and this leads to an effective shorter password.

How do you want to "salt" your password? "Salting" means to add artificial, random data to your actual data. If you salted your password it will get longer and thus the strength will increase, but also the password length. But if you cut the length down to your password length again, it is the same as generating a password with the original length alone and so the only effect is that you ignore some random bytes.
 
Old 02-10-2010, 08:52 PM   #3
jojothedogboy
LQ Newbie
 
Registered: Jun 2008
Posts: 12

Original Poster
Rep: Reputation: 0
Thanks for the reply! I'll start using this instead of just making up passwords!

RE Salting; I guess your right, the only way to create a stronger password would be through length or a larger pool of characters (or both).

I forgot to ask in the original post:
1. How to filter for character uniqueness
2. How to require at least one capital, lowercase, numeral, and special character? Also, would this detract from the overall password strength?
 
Old 02-11-2010, 07:10 AM   #4
irmin
Member
 
Registered: Jan 2010
Location: the universe
Distribution: Slackware (modified), Slackware64 (modified), openSuSE (modified)
Posts: 342

Rep: Reputation: 62
If you want to have each character appearing at most once in the password, I'd suggest to check in the generation loop, whether the character that should be added is already in the password. I did not find a simple solution, but this will do the work:

Code:
#!/bin/bash
MATRIX="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz!@#$%&*?-_=+)(}{][><"
LENGTH="8"
while [ "${n:=1}" -le "$LENGTH" ]
do
        RealRand=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -f1 -d" ")
	NEWCH=${MATRIX:$(($RealRand%${#MATRIX})):1}
	NPASS="${PASS//$NEWCH/}"
	[[ ${#NPASS} -lt ${#PASS} ]] && continue

        PASS="$PASS$NEWCH"

        #         echo "$PASS"
        let n+=1
done
echo "$PASS"      # ==> Or, redirect to a file, as desired.
exit 0
If you want to ensure the presence of a character of each category you may try:
Code:
CAT1="0123456789"
CAT2="abcdefghijklmnopqrstuvwxyz"
...

generate password

...
check for presence of category 1:
[[ "${PASS//[$CAT1]/}" == "$PASS" ]] && regenerate password

...
Another possibility is to count the characters in each category and change the MATRIX during the generation process. The above procedure will generate a password and then check if it meets the requirements and regenerate it, if needed.

The strength of the password depends on many parameters. Most passwords are chosen by humans and thus password crackers will search for patterns that are common in human generate passwords, like words or parts of words. Thus passwords containing only small letters can be regarded weak than passwords with special characters or mixed case (because less common in human generated patterns).

You could do a detailed analysis what patterns will have what probability to be cracked by "intelligent brute force" attacks. This calculation can be quite tedious. Also you need to make assumptions on the method the cracker may use: If he/she knows that all passwords are generated with maximum entropy, then it would weaken your password if you require the presence of certain kind of characters (this decreases entropy). On the other hand, if the cracker assumes human generated passwords, he/she will assume a lower entropy and thus the forced mixing will increase entropy and strengthen your password.

But your passwords are for FTP access and so you can assume the human generated scenario and the mixing will increase your password strength.
 
Old 02-11-2010, 07:27 AM   #5
jschiwal
Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 655Reputation: 655Reputation: 655Reputation: 655Reputation: 655Reputation: 655
irmin: You have /dev/random and /dev/urandom turned around. /dev/random gathers entropy to obtain the numbers.
The disadvantage is that it's entropy pool runs out quickly. You couldn't use /dev/random to obtain random numbers for a server generating keys or certificates because of a lack of random user interaction. You would use a random number device instead. The entropy is gathered from things like key press timing, mouse movement, clock jitter. The lower order bits will be random because you can't control the input to such a degree.

I don't think the OP understands what salt is. Salt is added to a password and then both together are hashed. It is chosen randomly from an acceptable character set. The salt is provided with the hash answer. This protects against dictionary attacks. Look in /etc/shadow for an example. The first two entries between the dollar signs are the hash type and the salt. The next is the hash itself.

I use /dev/random to supply 32 bytes to use when I change my wireless PSK, pipe it through od -t1x and then sed to remove the headers, spaces and returns. It is about the best password I could use unless I rolled 3 die 64 times.

Last edited by jschiwal; 02-11-2010 at 07:32 AM.
 
Old 02-11-2010, 08:18 AM   #6
cantab
Member
 
Registered: Oct 2009
Location: England
Distribution: *buntu, Vector
Posts: 499

Rep: Reputation: 102Reputation: 102
Quote:
Originally Posted by jojothedogboy View Post
1. How to filter for character uniqueness
2. How to require at least one capital, lowercase, numeral, and special character? Also, would this detract from the overall password strength?
Both of those things in theory reduce the password strength. Certainly, banning duplicate characters is misguided. Requiring one character from each class is more sensible, since an attacker may well try all lower-case

Also, what are these passwords for? If it's just for you, things may be fine, but if it's for other people, they're going to end up being written down because they're random gibberish.

Thus, a password with some structure is better. One type I've come across is three lowercase letters, three numbers, three uppercase letters. That gives about 3^11 3 x 10^11 possible passwords, which is about 2 orders of magnitude less than the fully random case. But for extra security, it could be lengthened. 3 lower, 4 numbers, 3 upper, and 1 symbol would equal 8 random in strength, and probably be more memorable.

Last edited by cantab; 02-11-2010 at 12:52 PM.
 
Old 02-11-2010, 11:20 AM   #7
irmin
Member
 
Registered: Jan 2010
Location: the universe
Distribution: Slackware (modified), Slackware64 (modified), openSuSE (modified)
Posts: 342

Rep: Reputation: 62
@cantab: How do you conclude from your statement that 3xlower case + 3xnumber + 3xupper case gives about 3^11 possible passwords? I obtain the following result: 26^3 * 10^3 * 26^3 = 308915776000, for the case where the groups are together and 26^3 * 10^3 * 26^3 * 9! / (3!)^3 = 518978503680000, for the case for also permuting the characters around. But 3^11 = 177147. But you're still right. In the total random case we have 62^9 = 13537086546263552 possibilities. That are two orders of magnitude more than for the permuted (3,3,3) case.

@jschiwal: You're right, I turned /dev/random and /dev/urandom around. Btw.: Does anybody know how the entropies of the PDFs for the generation of one bit generated by each devices are related to each other? For /dev/random the entropy will be near to log(2). What is the value for /dev/urandom? I'd expect it to be close to that of /dev/random, though smaller.
 
Old 02-11-2010, 12:53 PM   #8
cantab
Member
 
Registered: Oct 2009
Location: England
Distribution: *buntu, Vector
Posts: 499

Rep: Reputation: 102Reputation: 102
By writing the wrong thing, I meant 3 x 10^11. Fixed my previous post.
 
Old 02-12-2010, 02:36 AM   #9
jojothedogboy
LQ Newbie
 
Registered: Jun 2008
Posts: 12

Original Poster
Rep: Reputation: 0
jschiwal & irmin: your saying change from /dev/urandom to /dev/random, however, this server has no human interaction so jschiwal is saying I need to use some other means like "... use a random number device instead" to collect entropy... is this actually gonna make a big difference? Meaning, if I continue to use /dev/urandom instead of a "random number device" will my passwords be slightly more likely to be cracked or is it more like twice or more likely to be cracked?

Additionally, cantab makes a good point about the humans and their frequency of writing gibberish down... I'm afraid that these humans will be writing these passwords down and emailing them all over the place regardless. I've received complaints that some characters get confused when emailed (o/O/0 and I/l) ... hence removing them from the MATRIX. I'm not sure I see the clear choice here:
  1. A stronger password that will be written down and shared.
  2. A weaker password that will also be written down and shared but is less likely to be miss typed.

jschiwal: Two more things:
  1. You said,
    Quote:
    I use /dev/random to supply 32 bytes to use when I change my wireless PSK, pipe it through od -t1x and then sed to remove the headers, spaces and returns.
    so I tried
    Code:
    #dd if=/dev/random count=1 2> /dev/null | od -tx1
    #dd if=/dev/random ibs=32 2> /dev/null | cksum | od -tx1
    #dd if=/dev/random ibs=32 2> /dev/null | od -tx1
    but I get noting (like it gets stuck in a loop) and I have to CTR+C to stop it. May I please have a code example?
  2. I thought I understood "salting" from back in my PHP days. I would take a password input, add a phrase to it, then hash it for DB storage. Something like MD5('don't hack me',$POST[$pass]). Upon re-googleing I see there is more to it and will be reading up on it a little more, thanks.

Thanks everyone for all your help!
 
Old 02-12-2010, 03:04 AM   #10
jschiwal
Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 655Reputation: 655Reputation: 655Reputation: 655Reputation: 655Reputation: 655
You can use
dd if=/dev/random bs=32 count=1 | od -tx1. Note the block size and the count.
I pipe that into sed to get rid of the third line and the addresses starting the line, and the spaces.

You can also use "od -N 32 /dev/random" to read in 32 bytes. The dd command isn't necessary. I had only noticed this option lately myself.
Code:
$ od -N 32 /dev/random | sed  's/^.\{7\}//;s/ //g' | tr -d '\n'
007302117114163774045104046710045473107551042141112613110073010533172265015025116642106230073465
(note: example is using Cygwin/X at work. My not be random as a result)

I see that these two devices have their own manpages:
http://man.he.net/man4/urandom

Unless you are generating gpg keys, ssh keys or certificates, urandom should be OK. Linux writes a seed value when shutting down so the urandom device start from a different value when it boots.

/dev/random will block if it's entropy runs low. /dev/urandom doesn't block.

For generating passwords, it should be fine.

----

The old manpage for losetup had a section on generating random keys. The binary blobs were piped through the "uuencode" program to provide 7 bit ascii values. I don't know if all of these characters are acceptable for in a password and you may need to chop of the first three characters.

You could test if a candidate password contains an invalid character and reject that candidate if it does, or start with a candidate that is more than 8 characters, removing invalid characters and rechecking the string length.

Last edited by jschiwal; 02-12-2010 at 08:38 AM.
 
Old 02-12-2010, 09:36 AM   #11
cantab
Member
 
Registered: Oct 2009
Location: England
Distribution: *buntu, Vector
Posts: 499

Rep: Reputation: 102Reputation: 102
Quote:
Originally Posted by jojothedogboy View Post
Meaning, if I continue to use /dev/urandom instead of a "random number device" will my passwords be slightly more likely to be cracked or is it more like twice or more likely to be cracked?
The most obvious way anyone is going to be able to use your use of urandom to crack your password is if they have access to the computer generating the passwords. In that case they can probably just steal the generated passwords directly.

If you are generating a LOT of passwords in a short period of time, it's conceivable that knowledge of some of them would allow an attacker to deduce the 'state' of the random number generator, and thus the passwords they do not know. But this I very much doubt, especially since the attacker would need to know the sequence the passwords had been generated in as well as some of the passwords themselves.

In any case, the solution is simple - slow the generating rate a bit, and wiggle the mouse or mash on the keyboard while generating passwords.

Last edited by cantab; 02-12-2010 at 09:37 AM.
 
Old 02-12-2010, 10:43 AM   #12
tuxdev
Senior Member
 
Registered: Jul 2005
Distribution: Slackware
Posts: 2,014

Rep: Reputation: 115Reputation: 115
I use a script that uses a dictionary of 4096 real words and 8 punctuation, alternating between the two and picking a random item from each set. That's 12 bits and 3 bits of entropy respectively for each pool. A pretty decent password's 3 words and 2 punctuation, which comes out to 42 bits of entropy. Real words are *far* more memorable than some random collection of characters.
 
  


Reply

Tags
random number, shell script


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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 Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
help with password generator in C darkangel29 Programming 6 02-10-2009 01:08 PM
Want an easy password generator? Try this :) taskara Linux - General 4 07-25-2005 12:02 AM
written a password generator in C, get it here lepricaun General 1 08-09-2004 08:12 AM
Help: Need random password generator linuxgamer Linux - Software 5 12-02-2003 02:01 PM
Webmin automatic password generator ToBe Linux - General 2 08-26-2003 10:42 AM


All times are GMT -5. The time now is 10:27 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration