Board index » delphi » Re: Component to validate complex password

Re: Component to validate complex password


2008-01-18 10:12:32 AM
delphi278
Henrick Hellström writes:
Quote
You do know that there are other languages than American English? ;) For
a lot of languages these regular expressions would be a lot more complex
than they would in AE. This isn't necessarily a problem for a dictionary
that can be optimized for the specific language, but if you want to get
the same performance out of a regular expression, you would have to have
a single branched expression with a size proportional to the entire
dictionary.
I should probably add that the task is to determine, in O(n) time, that
it requires more than O(2^n) time to guess the password. The check I
propose is to verify, with as little false hits as possible, that it is
not possible to generate the pass phrase using a grammar, the 8000 most
common names and words in the language, and a small number (<10) of
other names and words. You can easily do that with a grammar check and
spell check, but how would you write regular expressions that would do it?
 
 

Re: Component to validate complex password

"Henrick Hellström" <XXXX@XXXXX.COM>writes
Quote
Dennis Jones writes:
>"Henrick Hellström" <XXXX@XXXXX.COM>writes
>>Wouldn't it be terribly inefficient to use regular expressions to check
>>for dictionary matches?
>
>Who cares? it is not as if it is going to execute thousands of times per
>second.

No, but such code would often run the first time the user uses the
software, and first impressions are important. Running through ~10.000 or
more regular expressions could take seconds, and if it has to do that
repeatedly (because the user enters several weak passwords in a row), you
have a user experience issue at hand.
But that is not what the OP asked for. He didn't ask for a dictionary
search. Just a quick *validation* that the password meets certain criteria,
and a regular expression (or a couple, at most) is perfect for that.
- Dennis
 

Re: Component to validate complex password

Dennis Jones writes:
Quote
But that is not what the OP asked for. He didn't ask for a dictionary
search. Just a quick *validation* that the password meets certain criteria,
and a regular expression (or a couple, at most) is perfect for that.
With all due respect, what a customer is asking for and what a customer
needs is sometimes two completely different things. If the OP now got
customers who are asking for password validation along the mentioned
criteria, it is not unheard of that they will sooner or later realize
what they really need are pass phrases (and in such case the validation
would have to be radically different).
 

Re: Component to validate complex password

Quote
I am looking for a component that can help validate and enforce complex
password requirements like "must contain at least one numeric", "must be
between 8-12 chars", etc. Any resource for this is greatly appreciated.
you can make the following function into a component if you want--I never
needed it that way (I have too many components as it is)
Edward Dressel
TPasswordRequirements = (pwrAllowSpaces, pwrChar, pwrUpperChar,
pwrLowerChar, pwrNumeric, pwrSymbol);
TPasswordRequirementSet = set of TPasswordRequirements;
function ContainsCharacter(const aString: string; const aChars: TCharSet):
boolean;
var
I: Integer;
begin
for I := 1 to Length(aString) do
if aString[I]in aChars then
begin
result := True;
exit;
end;
result := False;
end;
function CheckPassword(const aPassword: String; const aMinLength: integer;
const aRequirements: TPasswordRequirementSet; out aErrorMsg: String):
boolean;
const
SYMBOL_SET: TCharset =
['!','"','#','$','%','&','''','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\',']','^','_','`','{','|','}','~'];
var
lLowerChar: boolean;
lUpperChar: boolean;
begin
result := false;
if (aMinLength>0) and (Length(aPassword) < aMinLength) then
begin
aErrorMsg := Format('Password must be at least %d characters long.',
[aMinLength]);
exit;
end;
if (not (pwrAllowSpaces in aRequirements)) and (Trim(aPassword) <>
aPassword) then
begin
aErrorMsg := 'Password may not start or end with spaces.';
exit;
end;
lLowerChar := ContainsCharacter(aPassword, ['a'..'z']);
lUpperChar := ContainsCharacter(aPassword, ['A'..'Z']);
if (pwrChar in aRequirements) and (not (lLowerChar or lUpperChar)) then
begin
aErrorMsg := 'Password must contain an upper case character.';
exit;
end;
if (pwrUpperChar in aRequirements) and (not lUpperChar) then
begin
aErrorMsg := 'Password must contain an upper case character.';
exit;
end;
if (pwrLowerChar in aRequirements) and (not lLowerChar)then
begin
aErrorMsg := 'Password must contain a lower case character.';
exit;
end;
if (pwrNumeric in aRequirements) and (not ContainsCharacter(aPassword,
['0'..'9']))then
begin
aErrorMsg := 'Password must contain a numeric character.';
exit;
end;
if (pwrSymbol in aRequirements) and (not ContainsCharacter(aPassword,
SYMBOL_SET)) then
begin
aErrorMsg := 'Password must contain a symbol character.';
exit;
end;
result := True;
aErrorMsg := '';
end;
 

Re: Component to validate complex password

Hi Ed,
Sounds like a good solution for now. Thanks very much for the functions.
They helped a lot.
Andy
"Ed Dressel" <XXXX@XXXXX.COM>writes
Quote
>I am looking for a component that can help validate and enforce complex
>password requirements like "must contain at least one numeric", "must be
>between 8-12 chars", etc. Any resource for this is greatly appreciated.

you can make the following function into a component if you want--I never
needed it that way (I have too many components as it is)

Edward Dressel


TPasswordRequirements = (pwrAllowSpaces, pwrChar, pwrUpperChar,
pwrLowerChar, pwrNumeric, pwrSymbol);
TPasswordRequirementSet = set of TPasswordRequirements;

function ContainsCharacter(const aString: string; const aChars: TCharSet):
boolean;
var
I: Integer;
begin
for I := 1 to Length(aString) do
if aString[I]in aChars then
begin
result := True;
exit;
end;
result := False;
end;

function CheckPassword(const aPassword: String; const aMinLength: integer;
const aRequirements: TPasswordRequirementSet; out aErrorMsg: String):
boolean;
const
SYMBOL_SET: TCharset =
['!','"','#','$','%','&','''','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[','\',']','^','_','`','{','|','}','~'];
var
lLowerChar: boolean;
lUpperChar: boolean;
begin
result := false;
if (aMinLength>0) and (Length(aPassword) < aMinLength) then
begin
aErrorMsg := Format('Password must be at least %d characters long.',
[aMinLength]);
exit;
end;

if (not (pwrAllowSpaces in aRequirements)) and (Trim(aPassword) <>
aPassword) then
begin
aErrorMsg := 'Password may not start or end with spaces.';
exit;
end;

lLowerChar := ContainsCharacter(aPassword, ['a'..'z']);
lUpperChar := ContainsCharacter(aPassword, ['A'..'Z']);
if (pwrChar in aRequirements) and (not (lLowerChar or lUpperChar)) then
begin
aErrorMsg := 'Password must contain an upper case character.';
exit;
end;

if (pwrUpperChar in aRequirements) and (not lUpperChar) then
begin
aErrorMsg := 'Password must contain an upper case character.';
exit;
end;

if (pwrLowerChar in aRequirements) and (not lLowerChar)then
begin
aErrorMsg := 'Password must contain a lower case character.';
exit;
end;

if (pwrNumeric in aRequirements) and (not ContainsCharacter(aPassword,
['0'..'9']))then
begin
aErrorMsg := 'Password must contain a numeric character.';
exit;
end;

if (pwrSymbol in aRequirements) and (not ContainsCharacter(aPassword,
SYMBOL_SET)) then
begin
aErrorMsg := 'Password must contain a symbol character.';
exit;
end;

result := True;
aErrorMsg := '';
end;