Einzelnen Beitrag anzeigen

Benutzerbild von xZise
xZise

Registriert seit: 3. Mär 2006
Ort: Waldbronn
4.303 Beiträge
 
Delphi 2009 Professional
 
#1

Passwortsicherheit II (Delphi 2009)

  Alt 1. Feb 2009, 10:49
negaHs ( ) Passwortsicherheit arbeitet noch mit Ansistrings. Für Unicode muss das ganze verbreitert werden. Außerdem kann es da Bereichsüberprüfungsfehler geben, weshalb ich das jetzt mit Delphi 2009 bzw. Unicodestring kompatibel gemacht habe:
Delphi-Quellcode:
function PassphraseQuality(const Password : string): Extended;
// returns computed Quality in range 0.0 to 1.0
// source extracted from Delphi Encryption Compendium, DEC
// Convert to Delphi 2009 by Fabian (Nickname: xZise)

  function Diff(const AWord1, AWord2 : Word) : Word; overload;
  begin
    if AWord1 > AWord2 then
      Result := AWord1 - AWord2
    else
      Result := AWord2 - AWord1;
  end;

  function Diff(const AByte1, AByte2 : Byte) : Byte; overload;
  begin
    if AByte1 > AByte2 then
      Result := AByte1 - AByte2
    else
      Result := AByte2 - AByte1;
  end;

  {$IFDEF Unicode}
  function Entropy(P: PWordArray; L: Integer): Extended;
  {$ELSE}
  function Entropy(P: PByteArray; L: Integer): Extended;
  {$ENDIF}
  var
    Freq: Extended;
    I: Integer;
    {$IFDEF Unicode}
    Accu: array [Word] of LongWord;
    {$ELSE}
    Accu: array [Byte] of LongWord;
    {$ENDIF}
  begin
    Result := 0.0;
    if L <= 0 then Exit;
    FillChar(Accu, SizeOf(Accu), 0);
    for I := 0 to L-1 do Inc(Accu[P[I]]);
    for I := 0 to High(Accu) do
      if Accu[I] <> 0 then
      begin
        Freq := Accu[I] / L;
        Result := Result - Freq * (Ln(Freq) / Ln(2));
      end;
  end;

  function Differency: Extended;
  var
    S: string;
    L,I: Integer;
  begin
    Result := 0.0;
    L := Length(Password);
    if L <= 1 then Exit;
    SetLength(S, L-1);
    for I := 2 to L do
    begin
      {$IFDEF Unicode}
      Word(S[I-1]) := Diff(Word(Password[I-1]), Word(Password[I]));
      {$ELSE}
      Byte(S[I-1]) := Diff(Byte(Password[I-1]), Byte(Password[I]));
      {$ENDIF}
    end;

    Result := Entropy(Pointer(S), Length(S));
  end;

  function KeyDiff: Extended;
  const
    TableDE = '^1234567890ß´qwertzuiopü+asdfghjklöä#<yxcvbnm,.-°!"§$%&/()=?`QWERTZUIOPÜ*ASDFGHJKLÖÄ''>YXCVBNM;:_';
  var
    S: string;
    L,I,J: Integer;
  begin
    Result := 0.0;
    L := Length(Password);
    if L <= 1 then Exit;
    S := Password;
    UniqueString(S);
    for I := 1 to L do
    begin
      J := Pos(S[I], TableDE);
      if J > 0 then S[I] := Char(J);
    end;
    for I := 2 to L do
    begin
      {$IFDEF Unicode}
      Word(S[I-1]) := Diff(Word(S[I-1]), Word(S[I]));
      {$ELSE}
      Byte(S[I-1]) := Diff(Byte(S[I-1]), Byte(S[I]));
      {$ENDIF}
    end;
    Result := Entropy(Pointer(S), L-1);
  end;

const
  GoodLength = 10.0; // good length of Passphrases
var
  L: Extended;
begin
  Result := Entropy(Pointer(Password), Length(Password));
  if Result <> 0 then
  begin
    Result := Result * (Ln(Length(Password)) / Ln(GoodLength));
    L := KeyDiff + Differency;
    if L <> 0 then L := L / 64;
    Result := Result * L;
    if Result < 0 then Result := -Result;
    if Result > 1 then Result := 1;
  end;
end;
Ansonsten sollte sie genauso arbeiten wie die von negaH. Und vielleicht sollte man statt einen Compilerschalter das überladen lassen?

MfG
xZise
Fabian
Eigentlich hat MS Windows ab Vista den Hang zur Selbstzerstörung abgewöhnt – mkinzler
  Mit Zitat antworten Zitat