#!/usr/bin/perl # $Header: /u/cvsroot/passme/passme,v 1.3 2001/02/26 09:51:37 mayoff Exp $ use POSIX qw(ceil); $pieceType = 'character'; if ($ARGV[0] eq '-3') { $pieceType = '3'; shift; } # The user wants the generated passphrase to have at least $desiredBits bits # of entropy. $bitsDesired = shift; if ($bitsDesired !~ /^[0-9]+$/ || $bitsDesired == 0) { print STDERR "usage: $0 desired-bits\n"; exit(1); } if ($pieceType eq '3') { @pieces = qw( ace act add ado ads aft age ago aim air all and ant any ape apt arm art ash ask asp ass ate awe awl bad bag ban bar bat bay bed bee beg bet bib bid big bin bit boa bob bog boo bow box boy bra bud bug bum bun bus but buy bye cab cam can cap car cat caw cod cog con coo cop cot cow cry cub cue cup cut dad dam day den dew did die dig dim din dip doe dog don dot dry dub dud due dug dye ear eat ebb eel egg ego eke elf elk elm end era ere erg err fag fan far fat fed fee fen few fib fig fin fit fix flu fly fob foe fog for fox fro fry fun gab gad gag gap gas gay gel gem get gig gin gnu god got gum gun gut guy had hag ham hap has hat hay hem hen her hex hey hid him hip his hit hoe hog hop hot how hub hug hum hut ice icy ill imp ink inn ion ire irk its ivy jab jam jar jaw jay jet jig job jog jot joy jug jut ken key kid kin kit lab lad lag lap law lax lay led lee leg let lid lie lip lit lot low mad man map mat men met mew mid mix mob moo mop mud mug nab nag nap nay net new nil nip nod non nor not now nun nut oaf oak oar oat odd ode off oft ohm oil old opt orb ore out owe owl own pad pal pan par pat paw pay peg pen pep per pet pew phi pie pig pin pip pit ply pod pop pot pox pro pry pub pun pup pus put quo rag ram ran rap rat raw ray red rho rib rid rig rim rip rob rod rot rub rue rug rum run rut rye sad sag sap sat saw sax say sea see set sex she shy sip sir sit six ski sky sly sob sod son soy spa spy sub sue sum sun tab tag tan tap tar tau tax ten the tie tin tip tit ton top toy try tub tug ugh urn use van vat vex via vie vow wag wan war was wax way web wee wet who why wig win wit woe woo yes yet yon zoo ); $joiner = ' '; } else { @pieces = qw ( 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 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 9 . - ); $joiner = ''; } # If we pick a completely random piece from @pieces, we get $bitsPerPiece # bits of entropy. $bitsPerPiece = log(scalar(@pieces))/log(2); # So we need $piecesNeeded pieces... $piecesNeeded = ceil($bitsDesired/$bitsPerPiece); @passpieces = (); open(RANDOM, "/dev/random") || die "/dev/random: $!\n"; # $random is constructed by reading bytes from RANDOM. $random = 0; # $entropy is the number of bits of entropy contained in $random. $entropy = 0; while ($piecesNeeded > 0) { # $random needs to contain at least as many bits of entropy as # a random piece choice requires. while ($entropy < $bitsPerPiece) { # Use sysread so we read only as much as we need and don't # leave any wasted in a buffer at exit. sysread(RANDOM, $byte, 1) || die "/dev/random: $!\n"; $random = $random * 256 + ord($byte); $entropy += 8; } # Add a random piece to the passphrase. $pieceNumber = $random % scalar(@pieces); push(@passpieces, $pieces[$pieceNumber]); # Remove the used up bits of entropy from $random. $random = int($random / scalar(@pieces)); $entropy -= $bitsPerPiece; $piecesNeeded--; } print join($joiner, @passpieces), "\n"; exit(0); __END__ =head1 NAME passme - Create random passwords or passphrases =head1 SYNOPSIS B [B<-3>] desired-bits =head1 DESCRIPTION I creates random passwords. The program strings together random letters, digits, dashes, and periods (64 possible characters) to create a password with at least I bits of entropy. The program reads exactly C bytes from C and uses them to choose the characters in the password. Assuming that C produces truly random bytes, a random character from the program's set contains exactly 6 bits of entropy. A 66-bit password contains 11 characters. A 132-bit password contains 22 characters. The set of characters could be easily expanded to include all 94 printable ASCII characters (or 95 including spaces). However, this would only reduce the length of a 65-bit password to 10 characters, and of a 131-bit password to 20 characters. =head1 OPTIONS =over 5 =item B<-3> When given this flag, the program creates a passphrase built from a hard-coded list of 405 three-letter words. The list does not contain any words that are homonyms of other three-letter words. You may find this passphrase easier to remember than a password otherwise generated. A random word from the program's list contains approximately 8.66 bits of entropy. A passphrase of 8 words has about 69 bits of entropy. A passphrase of 15 words has about 130 bits of entropy. =head1 AUTHOR Rob Mayoff =head1 VERSION $Id: passme,v 1.3 2001/02/26 09:51:37 mayoff Exp $ =cut