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-----
The following archive was created by hippie-mail 7.98617-22 on Sat Apr 10 1999 - 01:18:27