Einzelnen Beitrag anzeigen

BlackSeven

Registriert seit: 25. Sep 2004
79 Beiträge
 
Delphi XE7 Professional
 
#10

AW: AES: Entschlüsselung JavaScript -> Delphi

  Alt 5. Feb 2013, 08:18
Entschlüsselung funktioniert nun. Zum Einsatz kommt DCPCrypt.

AES-256, CBC, Zero-Padding:
Delphi-Quellcode:
  aes:U2FsdGVkX1+aaWM2vHVan/zOH4E+9J2g/0Ylv4C1qgA=
  iv:34983c5eb8f1596da582a4aa93ca8016
  salt:9a696336bc755a9f
  ciphertext:fcce1f813ef49da0ff4625bf80b5aa00
  key:a28401b8f61012a6bde7a7a1df3f4303d6b009f9a5844a022a3ba4abbb0e6596
Meine Frage ist folgende:
Wie kann ich den Secret-Key aus Passwort, Salt und Iterations mithilfe einer Key derivation function (KDF) generieren? Im DEC gibt es zwar eine Funktion "KDF2", die liefert allerdings nur Müll.

Delphi-Code:
Delphi-Quellcode:
unit DCP.View;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    CipherText: TLabeledEdit;
    Key: TLabeledEdit;
    IV: TLabeledEdit;
    Decrypt: TButton;
    Text: TLabeledEdit;
    procedure DecryptClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  DCPcrypt2, DCPrijndael, DCPbase64, DCPmd5;

{$R *.dfm}

type

  TBuffer = record
  private
    FBytes: TBytes;
    function GetByte(const AIndex: Integer): Byte;
    function GetMemory: PByte;
    function GetSize: Int64;
    procedure SetByte(const AIndex: Integer; const AValue: Byte);
    procedure SetSize(const AValue: Int64);
  public
    constructor Create(const ABuffer: Pointer; const ASize: Integer);
    class function FromHexString(const AHexString: string): TBuffer; static;
    function ToRawByteString: RawByteString;
    property Bytes[const AIndex: Integer]: Byte read GetByte write SetByte; default;
    property Memory: PByte read GetMemory;
    property Size: Int64 read GetSize write SetSize;
  end;

constructor TBuffer.Create(const ABuffer: Pointer; const ASize: Integer);
begin

  SetLength(FBytes, ASize);

  if (Assigned(ABuffer) and (ASize > 0)) then
  begin

    Move(ABuffer^, FBytes[0], ASize);

  end;

end;

class function TBuffer.FromHexString(const AHexString: string): TBuffer;
const
  HexCharSet: TSysCharSet = ['0' .. '9', 'a' .. 'f', 'A' .. 'F'];

var
  Buffer: string;
  Bytes: TBytes;
  I: Integer;
  Index: Integer;
  Text: string;

begin

  Buffer := StringReplace(AHexString, '0x', '', [rfIgnoreCase, rfReplaceAll]);

  SetLength(Text, Length(Buffer));

  Index := 0;

  for I := 1 to Length(Buffer) do
  begin

    if CharInSet(Buffer[I], HexCharSet) then
    begin

      Inc(Index);

      Text[Index] := Buffer[I];

    end;

  end;

  SetLength(Bytes, (Index div 2));

  HexToBin(PWideChar(Text), PByte(Bytes), Length(Bytes));

  Result := TBuffer.Create(@Bytes[0], Length(Bytes));

end;

function TBuffer.GetByte(const AIndex: Integer): Byte;
begin

  Result := FBytes[AIndex];

end;

function TBuffer.GetMemory: PByte;
begin

  Result := PByte(FBytes);

end;

function TBuffer.GetSize: Int64;
begin

  Result := Length(FBytes);

end;

procedure TBuffer.SetByte(const AIndex: Integer; const AValue: Byte);
begin

  FBytes[AIndex] := AValue;

end;

procedure TBuffer.SetSize(const AValue: Int64);
begin

  SetLength(FBytes, AValue);

end;

function TBuffer.ToRawByteString: RawByteString;
begin

  Result := UTF8Encode(TEncoding.UTF8.GetString(FBytes));

end;

procedure RemoveZeroPadding(ABuffer: TBuffer);
var
  I: Integer;

begin

  for I := ABuffer.Size - 1 downto 0 do
  begin

    if ABuffer[I] = 0 then
    begin

      ABuffer.Size := ABuffer.Size - 1;

    end;

  end;

end;

procedure TForm1.DecryptClick(Sender: TObject);
// aes:U2FsdGVkX1+aaWM2vHVan/zOH4E+9J2g/0Ylv4C1qgA=
// iv:34983c5eb8f1596da582a4aa93ca8016
// salt:9a696336bc755a9f
// ciphertext:fcce1f813ef49da0ff4625bf80b5aa00
// key:a28401b8f61012a6bde7a7a1df3f4303d6b009f9a5844a022a3ba4abbb0e6596

var
  Cipher: TDCP_rijndael;
  I: Integer;
  LCipherText: TBuffer;
  LIV: TBuffer;
  LKey: TBuffer;

begin

  { Ciphertext }
  LCipherText := TBuffer.FromHexString(CipherText.Text);

  { Key }
  LKey := TBuffer.FromHexString(Key.Text);

  { IV }
  LIV := TBuffer.FromHexString(IV.Text);

  { Decryption }
  Cipher := TDCP_rijndael.Create(Self);
  try

    Cipher.Init(LKey.Memory^, 256, LIV.Memory);

    Cipher.DecryptCBC(LCipherText.Memory^, LCipherText.Memory^, LCipherText.Size);

    RemoveZeroPadding(LCipherText);

    Text.Text := LCipherText.ToRawByteString;

  finally
    Cipher.Free;
  end;

end;

end.
JS-Code:
Delphi-Quellcode:

  ...

  if ( bValid ) {

    var pwd = CryptoJS.AES.encrypt(user.val(), pass.val(),
          { padding: CryptoJS.pad.ZeroPadding }
);

    if (window.console) {
          console.log('user:%s pass:%s', user.val(), pass.val());
          console.log('aes:%s', pwd);
          console.log('iv:%s salt:%s ciphertext:%s', pwd.iv, pwd.salt, pwd.ciphertext);
          console.log('key:%s', pwd.key);
      }


  ...
  Mit Zitat antworten Zitat