AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Hilfe bei Umstellung Unit DEC5.1 zu DEC6.0
Thema durchsuchen
Ansicht
Themen-Optionen

Hilfe bei Umstellung Unit DEC5.1 zu DEC6.0

Ein Thema von haentschman · begonnen am 11. Jan 2024 · letzter Beitrag vom 31. Jan 2024
Antwort Antwort
Kas Ob.

Registriert seit: 3. Sep 2023
457 Beiträge
 
#1

AW: Hilfe bei Umstellung Unit DEC5.1 zu DEC6.0

  Alt 29. Jan 2024, 11:43
Please try this:
Code:
unit Tools.Crypt;

interface

uses
  System.SysUtils, DECUtil, DECHash, DECCipherBase, DECCiphers, DECHashBase,
  DECFormatBase, DECFormat, DECRandom, DECHashAuthentication;

const
  conKey = 'aYr14iaz8u)xO7Ok';

var
  //CipherAlgo: TCipher_Rijndael;
  CipherMode: TCipherMode = cmCBCx;
  HashClass : TDECHashClass = THash_SHA256;
  TextFormat: TDECFormatClass = TFormat_Base64;
  KDFIndex : Integer = 1; // Iterations

type
  TToolsCrypt = class
  public
    class function Decrypt(aHash: string; aKey: string = ''): string;
    class function Encrypt(aText: string; aKey: string = ''): string;
  end;

implementation

{ TToolsCrypt }

class function TToolsCrypt.Decrypt(aHash, aKey: string): string;
var
  Cipher: TCipher_Rijndael;
  //Cipher: TDECCipher;
  Salt, Data, Check, Pass, Mac: TBytes;
  MacLength, SaltLen, DataLen: Integer;
begin
  if aKey = '' then
  begin
    aKey := conKey;
  end;

  //Cipher:=ValidCipher(TCipher_Rijndael).Create;      // the way it should be used ! but it fail now with DecodeBytes
  Cipher := TCipher_Rijndael.Create;
  try
    MacLength := Cipher.Context.BlockSize;
    SaltLen := Cipher.InitVectorSize;

    Salt := ValidFormat(TextFormat).Decode(BytesOf(aHash));
    DataLen := Length(Salt) - MacLength - Cipher.Context.BufferSize;

    Data := Copy(Salt, MacLength, DataLen);
    Check := Copy(Salt, DataLen + SaltLen, Cipher.Context.BufferSize);

    SetLength(Salt, SaltLen);
    Pass := ValidAuthenticationHash(HashClass).KDFx(aKey[Low(aKey)], Length(aKey) * SizeOf(Char), Salt[Low(Salt)], Length(Salt), Cipher.Context.KeySize, KDFIndex);

    Cipher.Mode := CipherMode;
    Cipher.Init(Pass, nil);
    SetLength(Result, DataLen div SizeOf(Char));

    Cipher.Decode(Data[Low(Data)], Result[Low(Result)], DataLen);
    //Result := StringOf(Cipher.DecodeBytes(Data,TFormat_Copy));
    Mac := BytesOf(Cipher.CalcMAC);
    if MacLength < Length(Check) then
      MacLength := Length(Check);

    if (MacLength <> Cipher.Context.BlockSize) or (not CompareMem(Check, Mac, MacLength)) then
    begin
      Result := '';
    end;

  finally
    Cipher.Free;
    ProtectBytes(Salt);
    ProtectBytes(Check);
    ProtectBytes(Data);
    ProtectBytes(Pass);
    ProtectBytes(Mac);
  end;
end;

class function TToolsCrypt.Encrypt(aText, aKey: string): string;
var
  Cipher: TCipher_Rijndael;
  Salt, Pass, Data, Mac: TBytes;
begin
  if aKey = '' then
  begin
    aKey := conKey;
  end;

  Cipher := TCipher_Rijndael.Create;
  try
    Salt := RandomBytes(Cipher.InitVectorSize);
    Pass := ValidAuthenticationHash(HashClass).KDFx(aKey[Low(aKey)], Length(aKey) * SizeOf(Char), Salt[Low(Salt)], Length(Salt), Cipher.Context.KeySize, KDFIndex);
    Cipher.Mode := CipherMode;

    Cipher.Mode := cmCBCx;
    Cipher.Init(Pass, nil);

    SetLength(Data, Length(aText) * SizeOf(Char));
    Cipher.Encode(aText[Low(aText)], Data[Low(Data)], Length(Data));

    Mac := BytesOf(Cipher.CalcMAC);
    Result := StringOf(ValidFormat(TextFormat).Encode(Salt + Data + Mac));
  finally
    Cipher.Free;
    ProtectBytes(Salt);
    ProtectBytes(Pass);
    ProtectBytes(Data);
    ProtectBytes(Mac);
  end;
end;

end.
Kas
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.458 Beiträge
 
Delphi 12 Athens
 
#2

AW: Hilfe bei Umstellung Unit DEC5.1 zu DEC6.0

  Alt 30. Jan 2024, 08:31
Hallo...

Zum Verständnis:
Der Fehler kommt NICHT sofort, sondern nach hunderten Aufrufen des GLEICHEN SQL aus der Ressource. (Bild + SQL)
Das SQL wird JEDE Minute im Execute des Threads ausgeführt. Im Fehlerfalle (Fehlermeldung von einem anderen SQL) ist das SQL leer = beschädigt.
"[FireDAC][Phys][MSSQL]-306. Anweisungstext [] darf nicht leer sein."
Damit kann er auch den Parameter nicht finden...
Delphi-Quellcode:
procedure TDatabaseState.OfflineTime(Workstation: string; InstanzID: Integer; TimeStamp: TDateTime);
var
  Qry: TFDQuery;
begin
  Qry := CreateQuery;
  try
    Qry.SQL.Text := GetSQLByName('COM_OFFLINE_TIME');
    Qry.ParamByName('HAN').AsInteger := InstanzID; //<-
    Qry.ParamByName('TIM').AsDateTime := TimeStamp;
    Qry.ParamByName('WOR').AsString := Workstation;
    Qry.ExecSQL;
  finally
    Qry.Free;
  end;
end;
...
function TDatabaseBase.GetSQLByName(SQLName: string): string;
var
  SQLStream: TResourceStream;
  SQLStrings: TStringList;
  SQLStringsDecrypt: TStringList;
begin
  Result := '';
  SQLStrings := TStringList.Create;
  try
    SQLStringsDecrypt := TStringList.Create;
    try
      SQLStream := TResourceStream.Create(HInstance, SQLName, PWideChar(conDatabaseResourceGroupString));
      try
        try
          SQLStrings.LoadFromStream(SQLStream);
          SQLStringsDecrypt.Text := TToolsCrypt.Decrypt(SQLStrings.Text, conKey); //<-
          SQLStringsDecrypt.Delete(0); // Kommentar entfernen
          Result := SQLStringsDecrypt.Text;
        except
          Result := '';
        end;
      finally
        SQLStream.Free;
      end;
    finally
      SQLStringsDecrypt.Free;
    end;
  finally
    SQLStrings.Free;
  end;
end;
Zitat:
i asked for specific test vector to guarantee the migration of your code, and you didn't answer with one specific value
siehe hier: https://www.delphipraxis.net/1531964-post9.html

PS: Nach Umstellung wieder auf V5.2, ist bei den Usern wieder Ruhe...
Angehängte Grafiken
Dateityp: png Fehler.PNG (36,3 KB, 14x aufgerufen)
Angehängte Dateien
Dateityp: zip SQL_Time.zip (1.023 Bytes, 3x aufgerufen)

Geändert von haentschman (30. Jan 2024 um 08:43 Uhr)
  Mit Zitat antworten Zitat
Kas Ob.

Registriert seit: 3. Sep 2023
457 Beiträge
 
#3

AW: Hilfe bei Umstellung Unit DEC5.1 zu DEC6.0

  Alt 30. Jan 2024, 10:34
Hard bug to catch !, i can't reproduce this so will move to divide and conquer, for that we need to separate the decryption from MAC calculation.

Please try this, if you are in the mood to test deeper or you have time, this will show if the MAC is the failed point or not:
Code:
unit Tools.Crypt;

interface

uses
  System.SysUtils, DECUtil, DECHash, DECCipherBase, DECCiphers, DECHashBase,
  DECFormatBase, DECFormat, DECRandom, DECHashAuthentication;

const
  conKey = 'aYr14iaz8u)xO7Ok';

var
  CipherMode: TCipherMode = cmCBCx;
  HashClass: TDECHashClass = THash_SHA256;
  TextFormat: TDECFormatClass = TFormat_Base64;
  KDFIndex: Integer = 1; // Iterations

type
  TToolsCrypt = class
  public
    class function Decrypt(const aHash: string; out NoAuthResult: string; aKey: string = ''): string;
    class function Encrypt(const aText: string; aKey: string = ''): string;
  end;

implementation

{ TToolsCrypt }

class function TToolsCrypt.Decrypt(const aHash: string; out NoAuthResult: string; aKey: string): string;
var
  Cipher: TCipher_Rijndael;
  Salt, Data, Check, Pass, Mac: TBytes;
  MacLength, SaltLen, DataLen: Integer;
begin
  if aKey = '' then
  begin
    aKey := conKey;
  end;

  Cipher := TCipher_Rijndael.Create;
  try
    MacLength := Cipher.Context.BlockSize;
    SaltLen := Cipher.InitVectorSize;

    Salt := ValidFormat(TextFormat).Decode(BytesOf(aHash));
    DataLen := Length(Salt) - MacLength - Cipher.Context.BufferSize;

    Data := Copy(Salt, MacLength, DataLen);
    Check := Copy(Salt, DataLen + SaltLen, Cipher.Context.BufferSize);

    SetLength(Salt, SaltLen);
    Pass := ValidAuthenticationHash(HashClass).KDFx(aKey[Low(aKey)], Length(aKey) * SizeOf(Char), Salt[Low(Salt)], Length(Salt), Cipher.Context.KeySize, KDFIndex);

    Cipher.Mode := CipherMode;
    Cipher.Init(Pass, nil);
    SetLength(Result, DataLen div SizeOf(Char));

    Cipher.Decode(Data[Low(Data)], Result[Low(Result)], DataLen);
    NoAuthResult := Result;

    Mac := BytesOf(Cipher.CalcMAC);
    if MacLength < Length(Check) then
      MacLength := Length(Check);

    if (MacLength <> Cipher.Context.BlockSize) or (not CompareMem(Check, Mac, MacLength)) then
    begin
      Result := '';
    end;

  finally
    Cipher.Free;
    ProtectBytes(Salt);
    ProtectBytes(Check);
    ProtectBytes(Data);
    ProtectBytes(Pass);
    ProtectBytes(Mac);
  end;
end;

class function TToolsCrypt.Encrypt(const aText: string; aKey: string): string;
var
  Cipher: TCipher_Rijndael;
  Salt, Pass, Data, Mac: TBytes;
begin
  if aKey = '' then
  begin
    aKey := conKey;
  end;

  Cipher := TCipher_Rijndael.Create;
  try
    Salt := RandomBytes(Cipher.InitVectorSize);
    Pass := ValidAuthenticationHash(HashClass).KDFx(aKey[Low(aKey)], Length(aKey) * SizeOf(Char), Salt[Low(Salt)], Length(Salt), Cipher.Context.KeySize, KDFIndex);
    Cipher.Mode := CipherMode;

    Cipher.Mode := cmCBCx;
    Cipher.Init(Pass, nil);

    SetLength(Data, Length(aText) * SizeOf(Char));
    Cipher.Encode(aText[Low(aText)], Data[Low(Data)], Length(Data));

    Mac := BytesOf(Cipher.CalcMAC);
    Result := StringOf(ValidFormat(TextFormat).Encode(Salt + Data + Mac));
  finally
    Cipher.Free;
    ProtectBytes(Salt);
    ProtectBytes(Pass);
    ProtectBytes(Data);
    ProtectBytes(Mac);
  end;
end;

end.
When the result is empty check and log the content of NoAuthResult, please if possible log it in plain text and in HEX formatted form.
Kas
  Mit Zitat antworten Zitat
Benutzerbild von haentschman
haentschman

Registriert seit: 24. Okt 2006
Ort: Seifhennersdorf / Sachsen
5.458 Beiträge
 
Delphi 12 Athens
 
#4

AW: Hilfe bei Umstellung Unit DEC5.1 zu DEC6.0

  Alt 31. Jan 2024, 05:45
Hi...
Zitat:
Hard bug to catch !
...du sagst es.
Zitat:
or you have time
Guter Witz. Welcher Entwickler, der nicht allein ist, hat schon Zeit...

Ich werde das Thema wieder angehen, wenn die großen Themen des Jahres (neuer Quelltext) in Sack und Tüten sind.
In der Entwicklung kann ich über Nacht, im exception Block von GetSQLByName, ein Log schreiben das das Result aus TToolsCrypt protokoliert. In der Hoffnung, daß der Fehler dann auftritt. Das stelle ich dann zur Verfügung.
Im Release kann ich mich leider nicht darum kümmern...

Danke erstmal...
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 03:51 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