Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Neuen Beitrag zur Code-Library hinzufügen (https://www.delphipraxis.net/33-neuen-beitrag-zur-code-library-hinzufuegen/)
-   -   Delphi Passwortsicherheit II (Delphi 2009) (https://www.delphipraxis.net/128552-passwortsicherheit-ii-delphi-2009-a.html)

xZise 1. Feb 2009 10:49


Passwortsicherheit II (Delphi 2009)
 
negaHs ( :mrgreen: ) 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

mjustin 1. Feb 2009 11:19

Re: Passwortsicherheit II (Delphi 2009)
 
Zitat:

Zitat von xZise
Und vielleicht sollte man statt einen Compilerschalter das überladen lassen?

Oder

Delphi-Quellcode:
{$IF Declared(RTLVersion) and (RTLVersion >= 20.0)}
verwenden, ab Delphi 6 (oder auch früher?).

himitsu 1. Feb 2009 11:29

Re: Passwortsicherheit II (Delphi 2009)
 
Zitat:

Zitat von mjustin
Delphi-Quellcode:
{$IF Declared(RTLVersion) and (RTLVersion >= 20.0)}

es ist nicht gesagt, daß alle zukünftigen Delphi-Versioen auf Unicode laufen
und voallem was ist, wenn man 'nen Passwort im ANSI-Format in 'ner Unicode-Umgebung testen will?

Überladen wäre wohl praktischer :angel:

xZise 1. Feb 2009 11:45

Re: Passwortsicherheit II (Delphi 2009)
 
Aber damit wird das so riesig:
Delphi-Quellcode:
function PassphraseQuality(const Password : string): Extended; overload;
// 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 Entropy(P: PWordArray; L: Integer): Extended;
  var
    Freq: Extended;
    I: Integer;
    Accu: array [Word] of LongWord;
  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
      Word(S[I-1]) := Diff(Word(Password[I-1]), Word(Password[I]));
    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
      Word(S[I-1]) := Diff(Word(S[I-1]), Word(S[I]));
    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;

function PassphraseQuality(const Password : AnsiString): Extended; overload;
// 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 AByte1, AByte2 : Byte) : Byte; overload;
  begin
    if AByte1 > AByte2 then
      Result := AByte1 - AByte2
    else
      Result := AByte2 - AByte1;
  end;

  function Entropy(P: PByteArray; L: Integer): Extended;
  var
    Freq: Extended;
    I: Integer;
    Accu: array [Byte] of LongWord;
  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
      Byte(S[I-1]) := Diff(Byte(Password[I-1]), Byte(Password[I]));
    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
      Byte(S[I-1]) := Diff(Byte(S[I-1]), Byte(S[I]));
    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;
MfG
xZise

himitsu 1. Feb 2009 11:54

Re: Passwortsicherheit II (Delphi 2009)
 
aber man könnte dann überall beides nutzen :angel2:

Unicode in einem NichtUnicodeDelphi und ANSI in einem UnicodeDelphi

SP: String als Typ macht sich nicht gut ... in 'nem "alten" Delphi wäre Strin/AnsiString und läßt sich nicht mehr überarbeiten
und wenn jemand sein Delphi2009 auf ANSI umstellt ebenso :zwinker:

> WideString (und/oder seit D2009 UnicodeString)

mjustin 1. Feb 2009 13:34

Re: Passwortsicherheit II (Delphi 2009)
 
Zitat:

Zitat von himitsu
SP: String als Typ macht sich nicht gut ... in 'nem "alten" Delphi wäre Strin/AnsiString und läßt sich nicht mehr überarbeiten

Genau, Delphi 6 sagt zu dieser Deklaration:

Delphi-Quellcode:
function PassphraseQuality(const Password : AnsiString): Extended; overload;
[Fehler] Unit1.pas(112): Bezeichner redefiniert: 'PassphraseQuality'

da string = AnsiString

Weitere Fehler:

Delphi-Quellcode:
Word(S[I-1]) := Diff(Word(Password[I-1]), Word(Password[I]));
[Fehler] Unit1.pas(65): Der linken Seite kann nichts zugewiesen werden
[Fehler] Unit1.pas(90): Der linken Seite kann nichts zugewiesen werden

himitsu 1. Feb 2009 13:53

Re: Passwortsicherheit II (Delphi 2009)
 
Zitat:

Delphi-Quellcode:
Word(S[I-1]) := Diff(Word(Password[I-1]), Word(Password[I]));

Delphi-Quellcode:
// Convertierung auf andere Seite verlagern
// (es gibt zwar och 'nen Weg für die linke Seite,
// aber ich sollte lieber mal keine Pointer-Verrenkungen von mir geben ._. )
S[I-1] := WideChar(Diff(Word(Password[I-1]), Word(Password[I])));

// bzw für ANSI:
S[I-1] := AnsiChar(Diff(Byte(Password[I-1]), Byte(Password[I])));

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

function Diff(const AWord1, AWord2 : AnsiChar) : AnsiChar overload;


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:17 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz