📄 fips181.txt
字号:
number which is the encrypted form of the input.
The first function in the DES structure is setkey(), which converts
the pseudorandom key to a format used by DES for the encryption.
The command-line options sent to setkey are (0, 0, key). The first
0 is set so that setkey() does not generate parity; the second 0
tells setkey() that encryption (rather than decryption) is
required. Key is a pointer to the beginning of the key array.
After setkey(), the des() function is called. For input it uses
the addresses of the input and output arrays. Both input and
output are defined as unsigned character arrays of length 8 bytes.
The output array, out, is sent to a function, answer(), which
returns the final required number. The function answer() takes in
the address of the output array as an unsigned char pointer and the
integer n for which a value of 0 to (n-1) is needed by the random
word program. This function creates a variable sum, defined as an
unsigned integer. To obtain a numerical value from the output
character array, it adds the ASCII values of the first three
elements in the out array and stores the sum in the variable sum.
Thus, sum = out[0] + out[1] + out[2], which is an integer. To
obtain a number with the required range of 0 to n-1 from sum, the
function takes the modulus of sum and n, (sum%n). This value is
then returned to the calling function within the random word
program.
2.4 Random Word Algorithm
The algorithm used to generate random words is fixed and cannot be
modified without changing the logic of the program. The function
of the algorithm is to determine whether a given unit, generated by
the random unit subroutine, can be appended to the end of the
partial word formed so far. Rules of pronounceability are stored
in the unit and digram tables discussed above. The rules are used
to check if a given unit is legal or illegal. If illegal, the unit
is discarded and the random unit subroutine is called again. Once
a unit is accepted, various state variables are updated and a unit
for the next position in the word is tried. Most rules and checks
are syllable oriented and do not depend on anything outside the
current syllables. When the end of the word is reached, additional
checks are made before the algorithm terminates.
Passwords created by this automated password generator are composed
of the 26 characters of the English alphabet. Although numbers and
special characters are not permitted, the password space, which is
a function of the number of characters in the password, is very
large. Approximately 18 million 6-character, 5.7 billion 8-
character, and 1.6 trillion 10-character passwords can be created
by the program. Users should select a password space commensurate
with the level of security required for the information being
protected.
The password algorithm does not preclude the generation of words
found in a standard English dictionary. If required, a
computerized dictionary could be used to check for English words,
and the implementation could include software tests to prevent them
from being offered to users as passwords.
2.5 NIST Implementation
Figure 1 is a block diagram of the NIST implementation of the
automated password generation algorithm. Appendix A contains the
C-code for the DES, random key generation, and random word
generation routines that were used in the implementation (see
shaded boxes in Fig. 1). The personal computer used by NIST to
demonstrate the standard is implementation dependent. NIST
replaced the Unix random number routine in the original version of
the program with the "DES Randomizer" and "Generate Random Key"
function. The DES randomizer accepts an old password and a
pseudorandom key created in accordance with Appendix C of ANSI
X9.17 ( FIPSPUB 171) and generates a random number. This number is
used by the Random Word Generator to develop a password. As the
password is being generated each group of letters is subjected to
tests of grammar and semantics to determine if an acceptable word
has been created. If all tests are passed, the new password is
output to the PC.
In the NIST implementation, the values for minlen and maxlen, which
define the minimun and maximum size of the password, were set at 5
and 8 respectively. A user needing a fixed length password word
could set these variables to a specific value.
Appendix A
The following is a listing of the source code referenced in the
Automated Password Generator Standard.
/*
* randomword (word, hyphenated_word, minlen, maxlen, restrict,
seed)
*/
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#define RAN_DEBUG
#define B1
#define TRUE 1
#define FALSE 0
#define RULE_SIZE (sizeof(rules)/sizeof(struct unit))
#define ALLOWED(flag) (digram[units_in_syllable[current_unit -
1]][unit] & (flag))
#define MAX_UNACCEPTABLE 20
#define MAX_RETRIES (4 * (int) pwlen + RULE_SIZE)
#define NOT_BEGIN_SYLLABLE 010
#define NO_FINAL_SPLIT 04
#define VOWEL 02
#define ALTERNATE_VOWEL 01
#define NO_SPECIAL_RULE 0
#define BEGIN 0200
#define NOT_BEGIN 0100
#define BREAK 040
#define PREFIX 020
#define ILLEGAL_PAIR 010
#define SUFFIX 04
#define END 02
#define NOT_END 01
#define ANY_COMBINATION 0
typedef unsigned int uint;
typedef int boolean;
static int get_word();
static boolean have_initial_y();
static boolean illegal_placement();
static boolean improper_word();
static boolean have_final_split();
static char *get_syllable();
static unsigned short int random_unit();
static unsigned int randint();
static unsigned short int get_random();
static void set_seed();
extern char *calloc ();
extern char *malloc ();
extern char *strcpy ();
extern char *strcat ();
extern long time ();
extern long atol ();
extern double drand48();
extern int fscanf();
extern int fprintf();
struct unit
{
char unit_code[5];
unsigned short int flags;
};
static struct unit rules[] =
{
"a", VOWEL,
"b", NO_SPECIAL_RULE,
"c", NO_SPECIAL_RULE,
"d", NO_SPECIAL_RULE,
"e", NO_FINAL_SPLIT | VOWEL,
"f", NO_SPECIAL_RULE,
"g", NO_SPECIAL_RULE,
"h", NO_SPECIAL_RULE,
"i", VOWEL,
"j", NO_SPECIAL_RULE,
"k", NO_SPECIAL_RULE,
"l", NO_SPECIAL_RULE,
"m", NO_SPECIAL_RULE,
"n", NO_SPECIAL_RULE,
"o", VOWEL,
"p", NO_SPECIAL_RULE,
"r", NO_SPECIAL_RULE,
"s", NO_SPECIAL_RULE,
"t", NO_SPECIAL_RULE,
"u", VOWEL,
"v", NO_SPECIAL_RULE,
"w", NO_SPECIAL_RULE,
"x", NOT_BEGIN_SYLLABLE,
"y", ALTERNATE_VOWEL | VOWEL,
"z", NO_SPECIAL_RULE,
"ch", NO_SPECIAL_RULE,
"gh", NO_SPECIAL_RULE,
"ph", NO_SPECIAL_RULE,
"rh", NO_SPECIAL_RULE,
"sh", NO_SPECIAL_RULE,
"th", NO_SPECIAL_RULE,
"wh", NO_SPECIAL_RULE,
"qu", NO_SPECIAL_RULE,
"ck", NOT_BEGIN_SYLLABLE
};
static int digram[][RULE_SIZE] =
{
/* aa */ ILLEGAL_PAIR,
/* ab */ ANY_COMBINATION,
/* ac */ ANY_COMBINATION,
/* ad */ ANY_COMBINATION,
/* ae */ ILLEGAL_PAIR,
/* af */ ANY_COMBINATION,
/* ag */ ANY_COMBINATION,
/* ah */ NOT_BEGIN | BREAK | NOT_END,
/* ai */ ANY_COMBINATION,
/* aj */ ANY_COMBINATION,
/* ak */ ANY_COMBINATION,
/* al */ ANY_COMBINATION,
/* am */ ANY_COMBINATION,
/* an */ ANY_COMBINATION,
/* ao */ ILLEGAL_PAIR,
/* ap */ ANY_COMBINATION,
/* ar */ ANY_COMBINATION,
/* as */ ANY_COMBINATION,
/* at */ ANY_COMBINATION,
/* au */ ANY_COMBINATION,
/* av */ ANY_COMBINATION,
/* aw */ ANY_COMBINATION,
/* ax */ ANY_COMBINATION,
/* ay */ ANY_COMBINATION,
/* az */ ANY_COMBINATION,
/* ach */ ANY_COMBINATION,
/* agh */ ILLEGAL_PAIR,
/* aph */ ANY_COMBINATION,
/* arh */ ILLEGAL_PAIR,
/* ash */ ANY_COMBINATION,
/* ath */ ANY_COMBINATION,
/* awh */ ILLEGAL_PAIR,
/* aqu */ BREAK | NOT_END,
/* ack */ ANY_COMBINATION,
/* ba */ ANY_COMBINATION,
/* bb */ NOT_BEGIN | BREAK | NOT_END,
/* bc */ NOT_BEGIN | BREAK | NOT_END,
/* bd */ NOT_BEGIN | BREAK | NOT_END,
/* be */ ANY_COMBINATION,
/* bf */ NOT_BEGIN | BREAK | NOT_END,
/* bg */ NOT_BEGIN | BREAK | NOT_END,
/* bh */ NOT_BEGIN | BREAK | NOT_END,
/* bi */ ANY_COMBINATION,
/* bj */ NOT_BEGIN | BREAK | NOT_END,
/* bk */ NOT_BEGIN | BREAK | NOT_END,
/* bl */ BEGIN | SUFFIX | NOT_END,
/* bm */ NOT_BEGIN | BREAK | NOT_END,
/* bn */ NOT_BEGIN | BREAK | NOT_END,
/* bo */ ANY_COMBINATION,
/* bp */ NOT_BEGIN | BREAK | NOT_END,
/* br */ BEGIN | END,
/* bs */ NOT_BEGIN,
/* bt */ NOT_BEGIN | BREAK | NOT_END,
/* bu */ ANY_COMBINATION,
/* bv */ NOT_BEGIN | BREAK | NOT_END,
/* bw */ NOT_BEGIN | BREAK | NOT_END,
/* bx */ ILLEGAL_PAIR,
/* by */ ANY_COMBINATION,
/* bz */ NOT_BEGIN | BREAK | NOT_END,
/* bch */ NOT_BEGIN | BREAK | NOT_END,
/* bgh */ ILLEGAL_PAIR,
/* bph */ NOT_BEGIN | BREAK | NOT_END,
/* brh */ ILLEGAL_PAIR,
/* bsh */ NOT_BEGIN | BREAK | NOT_END,
/* bth */ NOT_BEGIN | BREAK | NOT_END,
/* bwh */ ILLEGAL_PAIR,
/* bqu */ NOT_BEGIN | BREAK | NOT_END,
/* bck */ ILLEGAL_PAIR,
/* ca */ ANY_COMBINATION,
/* cb */ NOT_BEGIN | BREAK | NOT_END,
/* cc */ NOT_BEGIN | BREAK | NOT_END,
/* cd */ NOT_BEGIN | BREAK | NOT_END,
/* ce */ ANY_COMBINATION,
/* cf */ NOT_BEGIN | BREAK | NOT_END,
/* cg */ NOT_BEGIN | BREAK | NOT_END,
/* ch */ NOT_BEGIN | BREAK | NOT_END,
/* ci */ ANY_COMBINATION,
/* cj */ NOT_BEGIN | BREAK | NOT_END,
/* ck */ NOT_BEGIN | BREAK | NOT_END,
/* cl */ SUFFIX | NOT_END,
/* cm */ NOT_BEGIN | BREAK | NOT_END,
/* cn */ NOT_BEGIN | BREAK | NOT_END,
/* co */ ANY_COMBINATION,
/* cp */ NOT_BEGIN | BREAK | NOT_END,
/* cr */ NOT_END,
/* cs */ NOT_BEGIN | END,
/* ct */ NOT_BEGIN | PREFIX,
/* cu */ ANY_COMBINATION,
/* cv */ NOT_BEGIN | BREAK | NOT_END,
/* cw */ NOT_BEGIN | BREAK | NOT_END,
/* cx */ ILLEGAL_PAIR,
/* cy */ ANY_COMBINATION,
/* cz */ NOT_BEGIN | BREAK | NOT_END,
/* cch */ ILLEGAL_PAIR,
/* cgh */ ILLEGAL_PAIR,
/* cph */ NOT_BEGIN | BREAK | NOT_END,
/* crh */ ILLEGAL_PAIR,
/* csh */ NOT_BEGIN | BREAK | NOT_END,
/* cth */ NOT_BEGIN | BREAK | NOT_END,
/* cwh */ ILLEGAL_PAIR,
/* cqu */ NOT_BEGIN | SUFFIX | NOT_END,
/* cck */ ILLEGAL_PAIR,
/* da */ ANY_COMBINATION,
/* db */ NOT_BEGIN | BREAK | NOT_END,
/* dc */ NOT_BEGIN | BREAK | NOT_END,
/* dd */ NOT_BEGIN,
/* de */ ANY_COMBINATION,
/* df */ NOT_BEGIN | BREAK | NOT_END,
/* dg */ NOT_BEGIN | BREAK | NOT_END,
/* dh */ NOT_BEGIN | BREAK | NOT_END,
/* di */ ANY_COMBINATION,
/* dj */ NOT_BEGIN | BREAK | NOT_END,
/* dk */ NOT_BEGIN | BREAK | NOT_END,
/* dl */ NOT_BEGIN | BREAK | NOT_END,
/* dm */ NOT_BEGIN | BREAK | NOT_END,
/* dn */ NOT_BEGIN | BREAK | NOT_END,
/* do */ ANY_COMBINATION,
/* dp */ NOT_BEGIN | BREAK | NOT_END,
/* dr */ BEGIN | NOT_END,
/* ds */ NOT_BEGIN | END,
/* dt */ NOT_BEGIN | BREAK | NOT_END,
/* du */ ANY_COMBINATION,
/* dv */ NOT_BEGIN | BREAK | NOT_END,
/* dw */ NOT_BEGIN | BREAK | NOT_END,
/* dx */ ILLEGAL_PAIR,
/* dy */ ANY_COMBINATION,
/* dz */ NOT_BEGIN | BREAK | NOT_END,
/* dch */ NOT_BEGIN | BREAK | NOT_END,
/* dgh */ NOT_BEGIN | BREAK | NOT_END,
/* dph */ NOT_BEGIN | BREAK | NOT_END,
/* drh */ ILLEGAL_PAIR,
/* dsh */ NOT_BEGIN | NOT_END,
/* dth */ NOT_BEGIN | PREFIX,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -