Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20091028210948.GA22674@openwall.com>
Date: Thu, 29 Oct 2009 00:09:48 +0300
From: Solar Designer <solar@...nwall.com>
To: john-users@...ts.openwall.com
Subject: Re: Incremental check with specific rule

This is an addition to my previous reply:

On Fri, Oct 23, 2009 at 04:12:29PM +0200, Joerg voelker wrote:
> I want to check passwords with the length of 8 or 9 chars. The passwords
> are all alpha-numeric. I know there is a password rule enforcing to use
> at least 1 upper, 1 lower and 1 numeric sign.
> 
> How can I tell JtR only to test passwords meeting these requirements?

Below is an external filter() that implements the above policy in a
fairly efficient way (of course, an approach not involving per-"word"
filtering would be even more efficient).  You use it like shown here:

http://www.openwall.com/lists/john-users/2009/02/10/3

[List.External:Policy]
int mask[0x100];

void init()
{
	int c;

	mask[0] = 0x100;
	c = 1;
	while (c < 0x100)
		mask[c++] = 0x200;

	c = 'a';
	while (c <= 'z')
		mask[c++] = 1;
	c = 'A';
	while (c <= 'Z')
		mask[c++] = 2;
	c = '0';
	while (c <= '9')
		mask[c++] = 4;
}

void filter()
{
	int i, seen;

/*
 * This loop ends when we see NUL (sets 0x100) or a disallowed character
 * (sets 0x200).
 */
	i = -1; seen = 0;
	while ((seen |= mask[word[++i]]) < 0x100)
		continue;

/*
 * We should have seen at least one character of each type (which "add up"
 * to 7) and then a NUL (adds 0x100), but not any other characters (would
 * add 0x200).
 */
	if (seen != 0x107)
		word = 0; // Does not conform to policy
}

Alternatively, you could want to assume that for human-chosen passwords
"at least one upper-case letter" usually means "exactly one" (and
usually in the first position).  You may then use an "incremental" mode
definition based on alnum.chr with variations of the following modifying
filter():

[List.External:Upper1]
int mask[0x100];

void init()
{
	int c;

	c = 0;
	while (c < 0x100)
		mask[c++] = 0;

	c = 'A';
	while (c <= 'Z')
		mask[c++] = 1;
}

void filter()
{
	if (mask[word[0] &= 0xDF]) // Convert to upper case
		return;

	word = 0; // Had a non-letter in the position, skip it
}

Please note that the above code (the second example only) does not
bother to check the length of the input word[].  Instead, it assumes
that, if you have it upper-case characters other than in or beyond the
first position, you use it only along with "incremental" mode
definitions with large enough MinLen.  For example, you may set both
MinLen and MaxLen to 8, and then define 8 variations of the external
mode above (to upper-case characters in positions 1-8).  Then you'd run
8 instances of JtR (maybe all at once on an 8-core system).

Alexander


Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.