Article View: sci.crypt
Article #961Re: Secure password generation
From: Marc Thibault
Date: Mon, 14 Sep 1992 14:19
Date: Mon, 14 Sep 1992 14:19
270 lines
8116 bytes
8116 bytes
In article <1992Sep12.020756.17214@morwyn.uucp>
(Forrie Aldrich) writes:
>
> I'm seeking a program/method which will generate pronounceable passwords,
> securely. Meaning the process by which the actual password is generated
> should be genuinely random enough so an attack at the algorithm (by
> whatever means) would be infeasable.
The C program listed below may be what Forrie is looking for,
but it needs a cryptographically strong RNG to replace
qrand(). Maybe one of our experts can post one??
----------------- START CODE -------------------------------------------
/* babble.c
A program to generate random pronounceable words to be
used as passwords.
Author: Marc Thibault
Created: 17 January 1988
Synopsis:
BABBLE [text]
Description:
BABBLE, sends 64 random words to STDOUT, each 8 followed by
a newline. If the optional [text] argument is provided, the
argument is used to initialize the random seed. The same argument
will result in the same words on successive calls.
The word generation is done through a set of arrays which
implement a strategy for pronounceability. This improves the
mnemonic value of the words without sacrificing randomness
to any significant degree.
Subroutines:
putns(c) add character to word
qrand(a) random integer between 0 and (a-1)
putSel(a,b) add element to word
selectStrategy () random row from strategy matrix
doSel(n) add element from set to word
makeWord() create random word
int utime() return unsigned int function of time
/*------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
/*------------------------------------------------------------------*/
/* Global Data Items
/*------------------------------------------------------------------*/
char word[16]; /* Babble words will be assembled here */
int wordCount; /* Count of characters in word */
/*------------------------------------------------------------------*/
/* Word Elements */
/*------------------------------------------------------------------*/
/* Introductory consonant */
char incon1[] = "bcdfghjklmnpqrstvwzsbbffpptdcst";
char incon2[] = " u tlrlrlrrrhhh";
/* Middle Consonants */
char midcon1[] = "bbcdffghjkllmmnpqrrrsssttvnz";
char midcon2[] = " s f l m u mr st t w ";
/* Ending Consonants */
char endcon1[] = "bcddfgklmnrssttvz";
char endcon2[] = " k ef t e y";
/* Vowels */
char vowels1[] = "aeiouaeieo";
char vowels2[] = " iaaeo";
/*------------------------------------------------------------------*/
/* put character if not space and wordCount<8 */
/* Returns 1 if character put, 0 if not */
/*------------------------------------------------------------------*/
char blank=32;
void putns(c)
char c;
{
if ((c != blank)&&(wordCount<8))
word[wordCount++] = c;
}
/*------------------------------------------------------------------*/
/* Return random number between 0 and argument
/* This needs a stronger RNG.
/*------------------------------------------------------------------*/
int qrand(a)
int a;
{
int r;
r=rand() % a;
return (r);
}
/*------------------------------------------------------------------*/
/* Put from selected array */
/*------------------------------------------------------------------*/
void putSel(a,b)
char a[], b[];
{
int i;
i=qrand(strlen(a));
putns(a[i]);
putns(b[i]);
}
/*------------------------------------------------------------------*/
/* Strategy Options
/* Each row is a sequence of choices representing constants
/* or vowels. See doSel for interpretation. The resulting
/* sequence is the template for a babble word. Greater security
/* can be obtained by increasing the size of the template.
/* If number of rows is changed, fix selectStrategy.
/* If number of cols is changed, fix makeWord.
/*------------------------------------------------------------------*/
int options[5][5]=
{
{1,2,1,4,0}, /* vowel, incon, vowel, endcon */
{1,3,1,4,0},
{2,1,3,1,0},
{2,1,4,1,0},
{2,1,3,1,4}
};
/*------------------------------------------------------------------*/
/* Return a random row number into options */
/*------------------------------------------------------------------*/
int selectStrategy ()
{
int i;
i = qrand(5);
return (i);
}
/*------------------------------------------------------------------*/
/* Handle one selection from a strategy
/*------------------------------------------------------------------*/
doSel(n)
int n;
{
switch(n)
{
case 0:
break;
case 1:
putSel(vowels1,vowels2);
break;
case 2:
putSel(incon1,incon2);
break;
case 3:
putSel(midcon1,midcon2);
break;
case 4:
putSel(endcon1,endcon2);
break;
}
}
/*------------------------------------------------------------------*/
/* Make a word
/* Fill word buffer with 5 option elements from one strategy
/*------------------------------------------------------------------*/
void makeWord()
{
int s; /* strategy selection */
int i; /* strategy element */
s=selectStrategy(); /* get a random strategy */
wordCount = 0; /* reset word buffer */
/* get 5 elements from selected strategy */
for (i=0; i<5; i++) doSel(options[s][i]);
word[wordCount]=0; /* terminate with nul */
}
/*------------------------------------------------------------------*/
/* Return daytime function as unsigned int
/*------------------------------------------------------------------*/
unsigned int utime()
{
return ( (unsigned)(time(NULL)%32768) );
}
/*------------------------------------------------------------------*/
/* MAIN PROGRAM */
/*------------------------------------------------------------------*/
main(argc,argv)
int argc;
char *argv[];
{
unsigned int i;
int j;
char *a; /* arg string for random seed */
unsigned int t0; /* initial time reading
/*--------------------------------------------------------------*/
/* Initialize Random Seed
/* If no argument is provided: use daytime, otherwise
/* add up bytes of argument
/*--------------------------------------------------------------*/
if( argc<2 )
{
/* Wait for time to change */
for (i=utime(); i==utime(););
/* set seed */
srand(utime());
}
else
{
i=0;
a=argv[1];
/* add up bytes in argument */
for (i=0; *a != 0; i += *a++);
srand(i);
}
/*--------------------------------------------------------------*/
/* Send 64 babble words to stdout */
/*--------------------------------------------------------------*/
for (i=0;i < 8; i++)
{
for (j=0; j<8; j++)
{
makeWord();
printf("%s ",word);
}
/* CRLF */
printf("\n");
}
/*---------------- That's All She Wrote ------------------------*/
}
---
Marc Thibault | | Any Warming,
marc@tanda.isis.org | Oxford Mills, Ontario | Global or otherwise,
CIS:71441,2226 | Canada | appreciated.
Technical Details
Message-ID:
<256379411DN5.61R@tanda.isis.org>Path:
arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!torn!cunews!revcan!micor!uuisis!tanda!marcReferences:
<1992Sep12.020756.17214@morwyn.uucp>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!sparky!uunet!cs.utexas.edu!torn!cunews!revcan!micor!uuisis!tanda!marc From: marc@tanda.isis.org (Marc Thibault) Reply-To: marc@tanda.isis.org Newsgroups: sci.crypt Subject: Re: Secure password generation Message-ID: <256379411DN5.61R@tanda.isis.org> References: <1992Sep12.020756.17214@morwyn.uucp> Date: Mon, 14 Sep 92 10:19:15 EDT Distribution: na Organization: Thibault & Friends Lines: 265