Re: Strengthening the Passphrase Model

New Message Reply About this list Date view Thread view Subject view Author view

David R. Conrad (drc@adni.net)
Thu, 11 Feb 1999 10:14:11 -0500 (EST)


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Wed, 10 Feb 1999, David R. Conrad wrote:

> Combine this with the suggestion of a "training mode" and perhaps the idea
> of writing down only part of the phrase, and it should be easy for most
> users to remember much better passphrases.

I was giving that some more thought this morning, and I decided to write
something to allow me to practise my passphrases. Here 'tis:

        -=-=- trial.c -=-=-
#include <stdio.h>
#include <curses.h>
#include <string.h>
#include <sha.h>

/*
 * the following controls whether we alert the user (visibly or audibly)
 * when they press backspace when the buffer is empty or type more
 * characters when the buffer is full (also see next pair of #defines)
 */
#define ALERT_ON_ERROR

/* uncomment one of these; beep for audible alert, or flash for visible */
#define ALERT() beep()
/* #define ALERT() flash() */

/* longest passphrase allowed is one less than this constant */
#define BUF_LEN 256

char *hashstr(char *);

int main(void)
{
    int c; /* character read from keyboard */
    int i; /* index into passphrase buffer */
    int y; /* screen y position of prompt */
    int x; /* screen x position of prompt */
    int line; /* current line to display hash on */
    char buf[BUF_LEN]; /* passphrase buffer */

    /* clear buffer */
    for (i = 0; i < BUF_LEN; i++) buf[i] = '\0';

    /* setup curses */
    initscr(); cbreak(); noecho(); nonl();
    intrflush(stdscr, FALSE);

    addstr("Enter a blank line (just press Return) to exit");
    mvaddstr(2, 0, "Enter passphrase: ");
    getyx(stdscr, y, x);
    refresh();
    line = 4;
    i = 0;
    while ((c = getch()) != ERR) {
        /* if Return was pressed before any characters were typed, exit */
        if ((c == 10 || c == 13) && i == 0) break;
        switch (c) {
            case 8:
            case 127:
                /* backspace -- remove last character from buffer */
                if (i > 0) buf[--i] = '\0';
#ifdef ALERT_ON_ERROR
                else { ALERT(); refresh(); }
#endif
                break;
            case 10:
            case 13:
                /* enter or return -- display hash of buffer */
                mvaddstr(line++, 4, hashstr(buf));
                if (line > 20) line = 4;
                move(line, 4);
                clrtoeol(); /* clear next line (like talk(1)) */
                move(y, x);
                refresh();
                /* clear buffer */
                for (i = 0; i < BUF_LEN; i++) buf[i] = '\0';
                i = 0;
                break;
            default:
                /* add character to buffer if it'll fit */
                if (i < BUF_LEN-1) buf[i++] = c;
#ifdef ALERT_ON_ERROR
                else { ALERT(); refresh(); }
#endif
        }
    }

    endwin();
    return 0;
}

/*
 * The only dependency on SSLeay is the sha.h header included at the top,
 * and the routine below. Thus it should be quite easy to alter this to
 * use a different crypto library for SHA-1, or even for a different hash
 * entirely. hashstr() just needs to return some unique hash of the
 * passphrase; the caller only displays it, doesn't try to examine it, so
 * it can be anything (but if the length changes, you need to ensure that
 * the static buffer is of sufficient size, natch)
 */

/*
 * compute the SHA-1 hash of a string, and then construct a 40-bit hash
 * from it by 'folding' it over twice with xor; convert the result to
 * hex and return the 10-character hash in a static buffer that is
 * overwritten on each call
 */
char *hashstr(char *str)
{
    static char hash[11];
    SHA_CTX sha;
    unsigned char dig[SHA_DIGEST_LENGTH];
    int i;

    SHA1_Init(&sha);
    SHA1_Update(&sha, str, strlen(str));
    SHA1_Final(dig, &sha);

    /* xor the n, n+5, n+10, and n+15 bytes of the hash together */
    for (i = 0; i < 5; i++)
      dig[i] ^= dig[i+5] ^ dig[i+10] ^ dig[i+15];

    /* fill the static buffer; chars get promoted to int when passed */
    sprintf(hash, "%.2x%.2x%.2x%.2x%.2x", dig[0],
      dig[1], dig[2], dig[3], dig[4]);

    return hash;
}
        -=-=- trial.c -=-=-

It comes with the following Makefile. Configure it for your compiler and
the location of SSLeay, or hack the code and the Makefile to use something
other than SSLeay for SHA-1, or even some other hash.

        -=-=- Makefile -=-=-
CC=gcc
CFLAGS=-O2 -I/usr/local/ssl/include
LDFLAGS=-L/usr/local/ssl/lib
LDLIBS=-lncurses -lcrypto
BINDIR=/usr/local/bin

trial: trial.o

trial.o: trial.c

install: trial
        install -c trial $(BINDIR)
        -=-=- Makefile -=-=-

Warning: it assumes ASCII codes for control characters.

Regards,

David R. Conrad <drc@adni.net> PGP keys (0x1993E1AE and 0xA0B83D31):
DSS Fingerprint20 = 9942 E27C 3966 9FB8 5058 73A4 83CE 62EF 1993 E1AE
RSA Fingerprint16 = 1D F2 F3 90 DA CA 35 5D 91 E4 09 45 95 C8 20 F1
Note: Due to frequent spam abuse, I accept no email from *.da.uu.net.

-----BEGIN PGP SIGNATURE-----
Version: PGPfreeware 5.0i for non-commercial use
Charset: noconv

iQA/AwUBNsLzz4POYu8Zk+GuEQLcsACgwst8hU4x9G1tn2aSqJxBPW/x5nsAnRta
57kRKruFwSHFwwAo41HaLaQx
=ZNKC
-----END PGP SIGNATURE-----


New Message Reply About this list Date view Thread view Subject view Author view

 
All trademarks and copyrights are the property of their respective owners.

Other Directory Sites: SeekWonder | Directory Owners Forum

The following archive was created by hippie-mail 7.98617-22 on Sat Apr 10 1999 - 01:18:27