stiftmaster - So 03.07.05 15:37
Titel: Rijndael (AES) Verschlüsselung in DLL: Zugriffsverletzung
Hallo Leute,
stecke zur Zeit an der AES-Verschlüsselung. Diese möchte ich in eine DLL packen. Das klappt auch soweit schon recht gut. Folgend der Code meiner DLL:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72:
| library Project1;
uses Cipher1 in 'Cipher1.pas', Classes, IdBaseComponent, IdCoder, IdCoder3to4, IdCoderMIME;
const Codes64 = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/';
function fEnc_Base64(const Value: string): string; var I, A, X, B: Integer; begin Result := ''; A := 0; B := 0; for I := 1 to Length(Value) do begin X := Ord(Value[I]); B := B * 256 + X; A := A + 8; while A >= 6 do begin A := A - 6; X := B div (1 shl A); B := B mod (1 shl A); Result := Result + Codes64[X + 1]; end; end; if A > 0 then begin X := B shl (6 - A); Result := Result + Codes64[X + 1]; end; end;
function fEnc_AES(const Value, Key: string): string; var AES: TCipher_Rijndael; begin AES := TCipher_Rijndael.Create(Key, nil); Result := AES.EncodeString(Value); AES := nil; AES.Free; end;
function EncodeString(const Value, Key: PChar): PChar; stdcall; var TempResult, TempKey, DummyString: string; begin try SetLength(TempResult, Length(Value) + 1); TempResult := Value;
SetLength(TempKey, Length(Key) + 1); TempKey := Key;
TempResult := fEnc_Base64(TempResult); >>> TempResult := fEnc_AES(TempResult, TempKey); Result := PChar(TempResult); except Result := Value; end; end;
exports EncodeString,
begin
end. |
Zum Testen habe ich mir ein kleines Programm gebastelt, um die Verschlüsselung zu testen. Dieses hat eine Memo-Eingabe und ein Label für die Ausgabe. Code wie folgt:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, Cipher1, IdBaseComponent, IdCoder, IdCoder3to4, IdCoderMIME;
type TForm1 = class(TForm) EncodeButton: TButton; Memo1: TMemo; Label1: TLabel; procedure EncodeButtonClick(Sender: TObject); private public end;
var Form1: TForm1;
const cDLL_Name = 'Project1.dll';
function EncodeString(const Value, Key: PChar): PChar; stdcall; external cDLL_Name;
implementation
{$R *.dfm}
procedure TForm1.EncodeButtonClick(Sender: TObject); var TempString: string; AES: TCipher_Rijndael; begin Label1.Caption := EncodeString(PChar(Memo1.Text), PChar('pwd'));; end;
end. |
In das Memo-Feld habe ich jetzt einfach n' bissle Delphi-Code kopiert, damit dieser verschlüsselt werden kann. Dieser sieht wie folgt aus:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44:
| Memo2 function DecodeString(Value, Key: PChar): PChar; stdcall; var AES: TCipher_Rijndael; Dec_Base64: TIdDecoderMIME; TempResult: string; begin try Result := Value;
Dec_Base64 := TIdDecoderMIME.Create(nil); AES := TCipher_Rijndael.Create(Key, nil);
TempResult := Dec_Base64.DecodeString(Value); TempResult := AES.DecodeString(TempResult); Result := PChar(TempResult); finally AES := nil; AES.Free; Dec_Base64 := nil; Dec_Base64.Free; end; end;function DecodeString(Value, Key: PChar): PChar; stdcall; var AES: TCipher_Rijndael; Dec_Base64: TIdDecoderMIME; TempResult: string; begin try Result := Value;
Dec_Base64 := TIdDecoderMIME.Create(nil); AES := TCipher_Rijndael.Create(Key, nil);
TempResult := Dec_Base64.DecodeString(Value); TempResult := AES.DecodeString(TempResult); Result := PChar(TempResult); finally AES := nil; AES.Free; Dec_Base64 := nil; Dec_Base64.Free; end; end; |
Wenn ich jetzt auf den Button klicke, funktioniert das Verschlüsseln einwandfrei, klicke ich öfters drauf, läuft es auch einwandfrei - aber irgendwann, nach dem X-ten klicken (mal ist es das zweite, mal das 10, mal das 30) kommt auf einmal eine Zugriffsverletzung aus der DLL.
Daraufhin habe ich den Code aus der DLL in die Unit kopiert, dort ebenfalls x-mal auf verschlüsseln geklickt und es kam einfach keine Zugriffsverletzugn.
Dann bin ich hingegangen und habe in der DLL nach und nach einige Zeilen auskommentiert um herauszubekommen, welche Zeile den Ärger macht. Irgendwann hatte ich die Zeile raus - es ist die mit der AES-Verschlüsselung, im Code mit >>> markiert. Lasse ich die draußen, gibt es keine Zugriffsverletzung aber auch keine Verschlüsselung ;-)
Kann sich das jemand von euch erklären. Was mache ich falsch - verstehe es einfach nicht...
Stefan
Moderiert von
raziel: Code- durch Delphi-Tags ersetzt.