Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi [DEC] WideString ver/entschlüsseln (https://www.delphipraxis.net/105894-%5Bdec%5D-widestring-ver-entschluesseln.html)

negaH 8. Jan 2008 16:47

Re: [DEC] WideString ver/entschlüsseln
 
Zitat:

Aber wenn ich einen WideString im Debugger beobachte hat es keine #0 im String ?!
Doch hat er, nur du betrachtest den WideString falsch. Oben schrieb ich explizit -> im Speicherauszug. Also im DebugView die Checkbox "Speicherauszug" anhacken, bitte ;)

Gruß hagen

xZise 8. Jan 2008 17:56

Re: [DEC] WideString ver/entschlüsseln
 
Hallo Mütze und Hagen,

ich glaube kaum, dass es tatsächlich am debugger liegt, dass er #0 einfügt.
Zitat:

Zitat von Muetze1
Zitat:

Zitat von xZise
Aber wenn ich einen WideString im Debugger beobachte hat es keine #0 im String ?!

Weil der Debugger um den Typ weiß und ihn entsprechend darstellt. Darstellung ist ungleich Ablage. Im Speicher liegt er trotzdem (bei Ansi-Inhalt) mit jedem 2. Byte als #0 vor! Wenn du einen "echten" Widestring wie unten verwendest, dann ist wird das jeweils zweite Byte ordentlich genutzt.

Jap... Aber ich meine, warum sollte er mitten drinne die Anzeige verändern?
Es ist die gleiche Variable vom Typ "WideString", also sollte der Debugger eigentlich selbstständig erkennen, dass es aus Words bzw. WideChars besteht?
Ich meine wenn man sowas macht:
Delphi-Quellcode:
var
  myWideString : WideString;

myWideString := 'Ein WideString';
myWideString := TueDasUndDas(myWideString);
Warum sollte, wenn als Ergebnis von TueDasUndDas wieder ein WideString herauskommt, aufeinmal #0 mitten im String auftauchen?

Zitat:

Zitat von Muetze1
Zitat:

Zitat von xZise
[edit=1]Ich habe es geradeeben getestet:
TTntEdit (namens e) auf dem Formular, und dann folgende Methode:

Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
var
  t : WideString;
begin
  t := e.Text;
  Showmessage(t);
  ShowMessage(t[2]);
end;
1. Showmessage gibt den WideString korrekt an.
2. Showmessage gibt das 2. Zeichen im WideString an (==> es ist kein #0 sondern das "dritte" Zeichen!)

WideString[] gibt dir auch einen WideChar zurück, und das ist ein Word. Wie willst du dort dann die Bytes betrachten?

Der indizierte Zeichenzugriff weiß doch um die Datenorganisation. Und wenn du WideString[] schreibst, dann gibst du das Zeichen an, auf das du zugreifen willst. Bei einem AnsiString[] ist es dann ein AnsiChar und der ist 8 Byte groß. Bei WideString[] ist es ein WideChar und der ist zwei Byte groß.


Delphi-Quellcode:
procedure TForm1.FormClick(Sender: TObject);
var
  t : WideString;
  lPtr: PByte;
begin
  t := e.Text;
  lPtr := @t[0];

  Showmessage(inttostr(lptr^) + ' ' + Chr(lPtr^));
  inc(lptr);
  Showmessage(inttostr(lptr^) + ' ' + Chr(lPtr^));
  inc(lptr);
  Showmessage(inttostr(lptr^) + ' ' + Chr(lPtr^));

  // alternativ:
  ShowMessage(format('high %d low %d', [Hi(t[2]), Lo(t[2])]));  // wenn er WideChar nicht bei Hi() und Lo() akzeptiert, dann caste auf Word...
end;

Nagut, dieser "Beweis" ist nicht ganz aussagekräftig.


Zitat:

Zitat von negaH
Zitat:

Aber wenn ich einen WideString im Debugger beobachte hat es keine #0 im String ?!
Doch hat er, nur du betrachtest den WideString falsch.[...]

Genau das gleiche wie oben: Warum sollte der Debugger auf einmal die Anzeige umschalten?

Nagut, selbst wenn ihr darauf einen Grund habt:
Ich habe diesmal debuggt mit Speicherauszug, und das Ergebnis seht hier:

Vor der Entschlüsselung und Verschlüsselung:
Code:
$68 $00 $74 $00 $74 $00 $70 $00 $3A $00 $2F $00 $2F $00 $77 $00 $77 $00 $77 $00 $2E $00 $67 $00 $6F $00 $6F $00 $67 $00 $6C $00 $65 $00 $2E $00 $64 $00 $65 $00
Nach der Entschlüsslung und Verschlüsselung:
Code:
$68 $00 [b]$00 $00[/b] $74 $00 [b]$00 $00[/b] $74 $00 [b]$00 $00[/b] $70 $00 $00 $00 $3A $00 $00 $00 $2F $00 $00 $00 $2F $00 $00 $00 $77 $00 $00 $00 $77 $00 $00 $00 $77 $00 $00 $00 $2E $00 $00 $00 $67 $00 $00 $00 $6F $00 $00 $00 $6F $00 $00 $00 $67 $00 $00 $00 $6C $00 $00 $00 $65 $00 $00 $00 $2E $00 $00 $00 $64 $00 $00 $00 $65 $00 $00 $00
(http://www.google.de)

Was sehen wir: 3 Byte (also genau 2 Byte zu viel) Nullen ;)
Ich habe nur die ersten 3 falschen Zeichen markiert.

MfG
xZise

[edit=1]Ich habe mal die Antwort verbessert...[/edit]
[edit=2]Ich habe das Ergebnis des Debuggers vor und nach der "Tortur" ( ;) ) angegeben und mal ein bisschen gehighlightet[/edit]

DGL-luke 8. Jan 2008 18:35

Re: [DEC] WideString ver/entschlüsseln
 
Tja, mein Verdacht: Irgendjemand interpretiert den Widestring als Ansistring und wandelt in wieder in einen Widestring um.

xZise 8. Jan 2008 18:47

Re: [DEC] WideString ver/entschlüsseln
 
Naja, da kommt an sich nur das Verschlüsseln etc. in betracht:
Delphi-Quellcode:
decryptedText := <WideString>; // Eine speicherung in der Variable, damit der Debugger den Inhalt anzeigt
str := EncryptW(<WideString>, <Passwort (WideString)>); // Verschlüsselung (PW + Text sind jetzt Widestrings)
if DecryptW(str, <Passwort (WideString)>, decryptedText) then // Entschlüsslung mit dem Passwort der Zeile drüber, also identisch
begin
  fs.Write(Pointer(str)^, Length(str)); // Speicherung des Strings
end;
1. Abfrage in der ersten Zeile und die zweite Abfrage nachdem er die 3. Zeile durchlaufen ist.

MfG
xZise

[edit=1]Interessant ist, dass die Entschlüsselung als Result dennoch true zurückgibt, obwohl sie eigentlich false ergeben sollte (oder?)[/edit]

Muetze1 8. Jan 2008 20:09

Re: [DEC] WideString ver/entschlüsseln
 
Alles von mir - auf was du dich so schön beziehst - hatte ich auf folgende 0-Bytes bezogen:

Zitat:

Zitat von xZise
Vor der Entschlüsselung und Verschlüsselung:
Code:
$68 [b]$00[/b] $74 [b]$00[/b] $74 [b]$00[/b] $70 [b]$00[/b] $3A [b]$00[/b] $2F [b]$00[/b] $2F [b]$00[/b] $77 [b]$00[/b] $77 [b]$00[/b] $77 [b]$00[/b] $2E [b]$00[/b] $67 [b]$00[/b] $6F [b]$00[/b] $6F [b]$00[/b] $67 [b]$00[/b] $6C [b]$00[/b] $65 [b]$00[/b] $2E [b]$00[/b] $64 [b]$00[/b] $65 [b]$00[/b]

Und in Bezug darauf, dass der Debugger diesen (ordentlichen) WideString natürlich als WideString ausgibt und somit diese oben genannten 0-Bytes nicht ausgibt. Und da dein Beispiel, um die 0-Bytes zu beweisen, wegen den WideChar niemals ein solchen bringen sollte, habe ich den ganzen Lex dort oben geschrieben.

Das bei dir im Endeffekt aber $00 $00 zusätzlich pro Zeichen im String sind, war nicht Gegenstand meines Beitrags.

/EDIT: Wir reden vollkommen aneinander vorbei. Von daher: vergiß es. Diskussion (mit mir) beendet.

xZise 8. Jan 2008 20:24

Re: [DEC] WideString ver/entschlüsseln
 
Zitat:

Zitat von Muetze1
Alles von mir - auf was du dich so schön beziehst - hatte ich auf folgende 0-Bytes bezogen:[...]

Ich habe doch nie geleugnet, dass bei WideStrings die #0 jedes 2. Byte sind, was ich aber ständig versuche zu zeigen, ist dass am Ende, da zwei Bytes zu viel auftauchen.
Und ich verstehe nicht so richtig, was du mir damit zeigst?

Ich könnte die natürlich in einer Schleife entfernen, oder der Fehler wird direkt eingedämmt.

MfG
xZise

negaH 8. Jan 2008 21:06

Re: [DEC] WideString ver/entschlüsseln
 
Also doch ein Wide-WideString. Irgendeine Typumwandlung macht aus einem WideString einen doppelt-gemoppelten Wide-WideString. Schau mal ob du bei MessageBoxW(PWideChar(WideStrng),...) mit MessageBoxW(PWideChar(@WideString[1]), ...) oder MessageBoxW(Pointer(@WideString[1]),...) was erreichen kannst.


Gruß Hagen

xZise 8. Jan 2008 22:28

Re: [DEC] WideString ver/entschlüsseln
 
Hi Hagen,
weder noch erreichen, dass der WideString dabei bleibt.

MfG
xZise

negaH 9. Jan 2008 21:20

Re: [DEC] WideString ver/entschlüsseln
 
Ok, probier das nochmal aus.

Delphi-Quellcode:
var
  ACipherClass: TDECCipherClass = TCipher_Rijndael;
  ACipherMode: TCipherMode = cmCBCx;
  AHashClass: TDECHashClass = THash_SHA1;
  ATextFormat: TDECFormatClass = TFormat_MIME64;
  AKDFIndex: LongWord = 1;

function Encrypt(const AText: WideString; const APassword: WideString): WideString;
var
  ASalt: Binary;
  AData: Binary;
  APass: Binary;
begin
  with ValidCipher(ACipherClass).Create, Context do
  try
    ASalt := RandomBinary(16);
    APass := ValidHash(AHashClass).KDFx(APassword[1], Length(APassword) * 2, ASalt[1], Length(ASalt), KeySize, TFormat_Copy, AKDFIndex);
    Mode := ACipherMode;
    Init(APass);
    SetLength(AData, Length(AText) * 2);
    Encode(AText[1], AData[1], Length(AData));
    Result := ValidFormat(ATextFormat).Encode(ASalt + AData + CalcMAC);
  finally
    Free;
    ProtectBinary(ASalt);
    ProtectBinary(AData);
    ProtectBinary(APass);
  end;
end;

function Decrypt(const AText: WideString; const APassword: WideString): WideString;
var
  ASalt: Binary;
  AData: Binary;
  ACheck: Binary;
  APass: Binary;
  ALen: Integer;
begin
  with ValidCipher(ACipherClass).Create, Context do
  try
    ASalt := ValidFormat(ATextFormat).Decode(AText);
    ALen := Length(ASalt) -16 -BufferSize;
    AData := System.Copy(ASalt, 17, ALen);
    ACheck := System.Copy(ASalt, ALen +17, BufferSize);
    SetLength(ASalt, 16);
    APass := ValidHash(AHashClass).KDFx(APassword[1], Length(APassword) *2, ASalt[1], Length(ASalt), KeySize, TFormat_Copy, AKDFIndex);
    Mode := ACipherMode;
    Init(APass);
    SetLength(Result, ALen div 2);
    Decode(AData[1], Result[1], ALen);
    if ACheck <> CalcMAC then
      raise Exception.Create('Invalid data');
  finally
    Free;
    ProtectBinary(ASalt);
    ProtectBinary(AData);
    ProtectBinary(ACheck);
    ProtectBinary(APass);
  end;
end;
Gruß Hagen

xZise 9. Jan 2008 21:31

Re: [DEC] WideString ver/entschlüsseln
 
Hallo Hagen,
mit dieser Version funktioniert.
Nun habe ich die "Stringausgabe"-Variante benutzt.
Vielleicht funktionierte die nur nicht...

MfG
xZise


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:17 Uhr.
Seite 3 von 3     123   

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