home *** CD-ROM | disk | FTP | other *** search
- Longer Passwords
- ================
-
-
- On Password Security
- --------------------
-
- Dr. (Bob) Wallis, recently commented on having faster implementations
- of DES available and suggested using a site dependant number of iterations
- of the DES algorithm as a secoundary keying variable to aid in stopping
- dictionary or brute force attacks. Having implemented a faster DES
- algorithm, and being extremely interested in the security aspect of
- passwords, I have a different suggestion.
-
- As I see it, their have been no published cases of cryptographic attack
- on passwords. There have been known cases of successful dictionary
- attacks. A dictionary attack is a successful match with the resulting
- syndrome from iterating the DES algorithm based on a known plaintext
- value ( all ZEROs ), and a suspected key ( from a dictionary of common
- passwords). There is a secoundary keying variable involved, a salt
- value providing modification to the E permutation, exchanging the
- first twelve and third twelve entries in a lookup table for finding
- the source location in the R register used as input to f(R,K).
-
- Secondary Keying Features
- -------------------------
-
- The salt value is intended to defeat the use of faster chip implementations
- of the DES algorithm. Having designed Gate Arrays, and drawn a set
- of schematics for the DES algorithm, the salt adds twelve dual, 2:1 Muxes
- and a 12 bit register to the basic algorithm. Even in an MSI
- implementation, and including the hardware for translating a block
- from the syndrome (passwd entry) and comparator for a match, the
- 16 pin equivalent count is less than 120. For hardware, salt is not
- relevant.
-
- Using tri-ranked registers for the R and L blocks, a 30 MHz clock,
- a dictionary held in a cache RAM, you could make 1.875 Million attempts
- per second on a single value. By comparing against the syndrome, instead
- of ZEROs, and adding the capability to change the target syndrome (from
- a RAM cache) the rate can be sustained for as many entries as you
- have syndrome cache. The problem is not the complexity of the DES
- algorithm, but instead the simplicity of the keys involved.
-
- Simple Passwords
- ----------------
-
- In The UNIX System: UNIX Operating System Security, AT&T Bell Laboratories
- -----------------------------------------------
- Technical Journal, Vol. 63, No. 8, Part 2 (Oct. 1984) pp. 1649-1672,
- F.T. Grampp and Robert H. Morris. The authors describe trying 20 of
- the most common female names, followed by a single digit, for a total
- of 200 passwords. At least one of these 200 was valid on each target
- machine.
-
- In Password Security: A Case History by Robert Morris and Ken Thompson,
- ---------------------------------
- the authors describes collecting 3,289 passwords over a period of time.
-
- Of those 15 were single characters, 72 were two char strings, 464 were
- three char strings, 477 were four char strings, 706 were 5 char strings
- and 605 were six char strings. Additionaly, 492 passwords appeared
- in various available dictionaries. 2,831 or 86 percent could be solved
- with a combination of dictionary and rule attacks. There have been two
- results of this:
-
- 1) more complex rules for acceptable passwords have been adopted.
-
- 2) an attempt has been made to either hide the algorithm (such as
- use of RSA) or hide the passwords (shadow password files).
-
- When combined with limiting attempts, hiding the algorithm or hiding
- the syndrome seriously slows down the time to enter a system.
-
- I have a graphics version of lock.c for my system, that can caste the
- required password to be that of any user. This allows real lock up of
- the console (using root or system password). It seems a shame to hide
- such stuff.
-
- These depend on scarcity of information, site security, and absolute
- control over machine access, which with the myrid of bugs, which seem
- to drift in and out of releases and various producers of UNIX compatible
- software and systems, secondary keying variables (including the number
- of iterations of DES), restrictions in password compostion, and otherwise
- proprietary algorithms do not seem to be an absolute guarantee against
- dictionary attack. The single biggest threat appears to be the size of
- the password. There should be some upper limit as to the size of a
- dictionary for a password attack. Pushing this limit should be a serious
- deterrent.
-
- Longer Passwords
- ----------------
-
- Using longer passwords should require a lower bound on the size
- (which could be measured without included common pronouns and adjectives.)
-
-
-
- There are several requirements for longer passwords:
-
- 1) longer passwords must produce distinct syndromes (their syndromes
- should not match those for partial products).
-
- 2) The syndromes should not map into syndromes from existing
- dictionary attack.
-
- 3) retention of present password system (Increasing the size and
- complexity of the dictionary and rule attack systems).
-
- Instead of a set of rules for a password of at most 8 characters, we
- now have two set of rules, including a set for passwords of more than
- 8. If rules are included for longer passwords to prevent the use of
- simple phrases, as is done for shorter passwords, A dictionary attack
- can become more than linearly larger.
-
- To prevent detection of the size of the password, entries in the password
- file should be of identical length.
-
- Implementation
- --------------
-
- A sample crypt routine with modifications for longer passwords is
- appended. This is for use with my implementation of DES, but shows
- how longer passwords can be handled. Also appended is lmakekey.c
- which generates password file passwd_entries for longer passwords.
- The input has not been blanked. It also allows multiple passwords
- with the same salt to executed and output to a file. A sample of
- its execution for strings length 8 34 using -
- "mississippi riverboat gambling man" as an input. The salt used
- is the null salt "..".
-
- I may well publish my DES implementation in the future. It is 3.4
- times faster than the DES found in libcrypt. I can get approximately
- 10 Kbytes/sec on my IRIS 4D-25/G when implemented in a program
- doing read() and write()'s in 8 byte chunks. The progam also supports
- a test vector file for implementation verification.
-
- The implementation is present system compatible for passwords 8 or
- fewer characters long. The salt value is always used.
-
- For passwords greater than 8 characters, The last 8 characters are used
- as key. The initial block is cleared to zeros, and the first byte
- of key is EXORed with the first byte of the 8 byte block string.
- A DES iteration is performed. For all remaining password bytes not
- involved in the key, each is then EXORed with location[0] of the byte
- string, followed by an iteration of DES. If less than 25 iterations of
- DES have taken place, DES is iterated until 25 iterations have taken
- place. Note, that in the character array implementation of DES used,
- the password bytes used as data are not left shifted to leave bit 0
- blank, as is done by the routine loadkey(). To produce the results
- shown appended, the following mapping equivalency is helpful.
-
- The mapping equivalency is:
-
- L/R[ ] data.string[0] ([3] for little_endian)
-
- L[31] Bit 0
- R[31] Bit 1
- L[23] Bit 2
- R[23] Bit 3
- L[15] Bit 4
- R[15] Bit 5
- L[ 7] Bit 6
- R[ 7] Bit 7
-
-
- My system performs big_endian byte in long ordering: byte order is 0123.
- This is motorola compatible. Little endian systems should use
- data.string[3] instead. My implementation of DES can be compiled for
- any _endian system.
-
- Note that Bit 7 (R[7]) can be expected to be a ZERO for ascii, resulting
- in at most 7 bits of divergence from the value of the current block
- for each byte of the password.
-
- System Impact
- --------------
-
- A new getpass() routine is needed. This appears to be a good place
- to do some rule checking based on length.
-
- A new passwd and login program are needed for longer passwords.
-
- A maximum size password need be specified for writing portable code.
-
- A new crypt(pw,salt) routine for longer passwords is needed.
-
- libPW may be immune from impact.
-
-
- APPENDS
- -------
-
- =============
- crypt routine - based on a long aligned char string block
- =============
- char * lcrypt(pw,salt)
- char *pw, *salt;
- {
- int i,c,e, bit, ci, pw_len;
- static char outbuf[16];
- union LR_block data; /* long aligned char array[9] */
-
- for (pw_len = 0; pw[pw_len];pw_len++) /* pw_len = strlen(pw) */
- ;
- for (i = 0; i< 8;i++) /* strncpy(data.string,pw,8); */
- if ( pw_len > 8)
- data.string[i] = pw[i + pw_len-8] ; /* last 8 chars */
- else
- data.string[i] = pw[i];
-
- loadkey(data.string,1); /* first 8 chars nulled */
- data.string[8] = 0; /* needed for outbuf conversion */
-
- toggle_E(salt); /* for new implementation des */
-
- if ( pw_len < 9)
- for(i= 0; i < 25; i++)
- des(&data,0); /* faster encrypt() */
-
- else {
- for(i=0; i < pw_len - 8; i++) {
- data.string[1] ^= pw[i];
- des(&data,0);
- }
- if ( (i = (25 - (pw_len-8)) > 0)) /* at least 25 iterations */
- while ( i-- )
- des(&data,0);
- }
-
- toggle_E(salt); /* undo for sucessive crypt() calls */
-
- for (i = 2,ci = 0, bit = 7; i < 13;i++) {
- c = 0;
- for ( e = 5; e >= 0 ; e--){
- if (bit < 0 ) {
- ci++;
- bit = 7;
- }
- if (BIT(bit--) & data.string[ci])
- c |= BIT(e);
- }
- c += '.';
- if (c > '9')
- c += 7;
- if (c > 'Z')
- c +=6;
- outbuf[i] = c;
- }
- outbuf[i] = 0;
- outbuf[0] = salt[0];outbuf[1] = salt[1];
- if (outbuf[1] == 0)
- outbuf[1] = outbuf[0];
- return(outbuf);
- }
- ==========
- lmakekey.c
- ==========
- #include <stdio.h>
- #include <string.h>
-
- extern char *lcrypt();
-
- #define STRLEN 128
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- int i;
- char key[BUFSIZ], salt[BUFSIZ], *password;
- FILE *outfile;
- int firstpass = 1;
- if ( argc == 2) {
- if ( (outfile = fopen(argv[1],"a")) == NULL) {
- fprintf(stderr,"ERROR: %s, can't open %s for append\n",
- argv[0],argv[1]);
- }
- }
-
- while ( argc == 2 || firstpass){
-
-
- fprintf(stdout,"Password? ");
- fgets(key,STRLEN,stdin);
-
- if( strlen(key) > STRLEN)
- key[STRLEN] = 0;
-
- for (i = 0; i < STRLEN; i++)
- if (key[i] == '\n')
- key[i] = 0;
-
- if (firstpass) {
- fprintf(stdout,"Salt? ");
- fgets(salt,STRLEN,stdin);
- }
-
- if ( strlen(salt) > 2)
- salt[2] = 0;
-
- password = lcrypt( key, salt);
- fprintf(stdout,"%s\n",password);
-
- if (argc == 2)
- fprintf(outfile,"length = %3d, passwd= %s, in: %s\n",
- strlen(key),password, key);
- firstpass = 0;
- fflush(outfile);
- }
- return(0);
- }
- =======================
- sample longer passwords
- =======================
- length = 8, passwd= ..7kVXGzGEb7Y, in: mississi /* crypt() compatible */
- length = 9, passwd= ..C8v9PtCB.0Y, in: mississip
- length = 10, passwd= ..qjDDYqQvBlA, in: mississipp
- length = 11, passwd= ..cSxjNmzNjEI, in: mississippi
- length = 12, passwd= ..bPSqz0AtIu6, in: mississippi
- length = 13, passwd= ..hAmDw39a32k, in: mississippi r
- length = 14, passwd= ..3enRY0SxJCs, in: mississippi ri
- length = 15, passwd= ..tid0WYNoPrs, in: mississippi riv
- length = 16, passwd= ..RCEkliTOVH6, in: mississippi rive
- length = 17, passwd= ..C/GbzVyN5Hc, in: mississippi river
- length = 18, passwd= ..3/rSfkQ5nDs, in: mississippi riverb
- length = 19, passwd= ..FWryDwutGyQ, in: mississippi riverbo
- length = 20, passwd= ..J8KOcjnnn6Y, in: mississippi riverboa
- length = 21, passwd= ..tMv7dg6ksbE, in: mississippi riverboat
- length = 22, passwd= ..cpUzQd3uyuQ, in: mississippi riverboat
- length = 23, passwd= ..kO8JORivC8g, in: mississippi riverboat g
- length = 24, passwd= ..ypuS9WWIJc2, in: mississippi riverboat ga
- length = 25, passwd= ..XGZDJsPLNic, in: mississippi riverboat gam
- length = 26, passwd= ..niG1hl1tjW2, in: mississippi riverboat gamb
- length = 27, passwd= ..AB8aRp181jA, in: mississippi riverboat gambl
- length = 28, passwd= ..zr068aSaFE2, in: mississippi riverboat gambli
- length = 29, passwd= ..6UY6NO.J6R., in: mississippi riverboat gamblin
- length = 30, passwd= ..w0m5AQ2XxFw, in: mississippi riverboat gambling
- length = 31, passwd= ..sYSNGs6qUww, in: mississippi riverboat gambling
- length = 32, passwd= ..xZ0//Llq3Ck, in: mississippi riverboat gambling m
- length = 33, passwd= ..MFsadQbW1LA, in: mississippi riverboat gambling ma
- length = 34, passwd= ..riGwJEykDBQ, in: mississippi riverboat gambling man
- ---------------------------------------------------------------------------
-
-
-