дешифрование с помощью rijndael. Библиотека DCPcrypt. Delphi - PullRequest
0 голосов
/ 20 ноября 2010

У меня есть IV (вектор инициализации) и ключ, а также криптограмма.Мне нужно расшифровать криптограмму.Из Интернета я нашел Библиотека криптографических компонентов DCPcrypt v2 .Итак, теперь я дошел до кодирования.

procedure TForm1.Button1Click(Sender: TObject);
var
key:Ansistring;
ivector,indata,outdata:string;
begin
  key := 'abc12345679';  //<--key for decrypting
  dcp_rijndael1.InitStr(key,TDCP_sha1);  //I don't understand why i need hashing!?

  ivector := edit2.Text;  //initialization vector
  dcp_rijndael1.SetIV(ivector);
  dcp_rijndael1.BlockSize := Length(ivector); //'This variable should be the same size as the block size' says the documentation

  indata := edit1.Text;  //getting the cryptogram

  dcp_rijndael1.CipherMode := cmCBC;

  dcp_rijndael1.DecryptCBC(indata,outdata,Length(indata));
  label3.Caption := outdata;                                    //output to label
end;

Этот код выдает мне ошибку.Окно «Локальные переменные» отображает индата, исходные данные, ivector, ключевые переменные как «Недоступное значение».Или, может быть, есть другой способ сделать это.Это кажется довольно прямым, хотя.Заранее спасибо.

После помощи Wodzu: Обратите внимание, что я получаю расшифрованную строку, закодированную с base64, так что я думаю, мне нужно сначала ее декодировать.

var
  Form1: TForm1;
  StringToEncrypt, StringToDecrypt, DecryptedString: string;
  vector:string;

procedure TForm1.Button2Click(Sender: TObject);
begin
  vector := '1234567812345678';        //Length 16
  stringtodecrypt := '2YOXZ20Z7B3TRI/Ut8iH/GpEZWboE2tnnWU';
  stringtodecrypt := Decode64(stringtodecrypt);  //after encrypted string is sent over internet, it is encoded with base64, so i need to decode it.
  SetLength(DecryptedString, 36);  //36 is the length of the output
  DCP_rijndael1.Init('MyKey:128bit', 128, @Vector[1]);
  DCP_rijndael1.SetIV(Vector);
  DCP_rijndael1.BlockSize := Length(Vector); //Should this be also 128
  DCP_rijndael1.DecryptCBC(StringToDecrypt[1], DecryptedString[1], Length(StringToDecrypt)*2);  //Here i get hieroglyph as a result. Why is length multiplied with 2?
  decryptedstring := Encode64(decryptedstring);  //Here i get less hieroglyph, but would like to get correct decrypted string. I doubt the necessity of encoding

  ShowMessage(DecryptedString);

end;

Я не могу сделать этот код для расшифровки данных, которые кто-то другой шифрует (с помощью PHP) (после шифрования данные кодируются с помощью base64). Примечание! длина зашифрованного текста не совпадает с длиной зашифрованного текста!

Ответы [ 4 ]

1 голос
/ 27 ноября 2010

Если у вас возникли проблемы с кодом, который я выложил ранее, попробуйте эту версию с потоками.

procedure TForm1.Decrypt(const aKey: AnsiString; aPVector: Pointer;
  var aInData, aOutData: TMemoryStream);
var
  Cipher : TDCP_rijndael;
begin
  Cipher := TDCP_rijndael.Create(nil);
  try
    Cipher.Init(aKey, Length(aKey)*8, aPVector);
    Cipher.CipherMode := cmCBC;
    Cipher.DecryptStream(aInData, aOutData, aInData.Size);
  finally
    Cipher.Burn;
    Cipher.Free;
  end;
end;

и вот как ее использовать:

var
  din, dout: TMemoryStream;
  Vector: array of byte;
begin


SetLength(Vector, 16);

Vector[1] := 1;
Vector[2] := 2;
Vector[3] := 9;
Vector[4] := 0;
Vector[5] := 6;
Vector[6] := 1;
Vector[7] := 6;
Vector[8] := 7;
Vector[9] := 5;
Vector[10] := 8;
Vector[11] := 3;
Vector[12] := 1;
Vector[13] := 7;
Vector[14] := 3;
Vector[15] := 3;
Vector[16] := 8;

din := TMemoryStream.Create;
dout := TMemoryStream.Create;
try
  din.LoadFromFile('Encrypted.DAT');
  din.Position := 0;
  decrypt('4tkF4tGN1KSiwc4E', addr(Vector[1]), din, dout);
  dout.SaveToFile('Decrypted.DAT');
finally
  din.Free;
  dout.Free;
end;

и версия для строк:

procedure TForm1.Decrypt(const aKey: AnsiString; aPVector: Pointer;
   const aInData: AnsiString; var aOutData: AnsiString);
var
  Cipher : TDCP_rijndael;
begin
  Cipher := TDCP_rijndael.Create(nil);
  try
    Cipher.Init(aKey, Length(aKey)*8, aPVector);
    Cipher.CipherMode := cmCBC;
    aOutData := Cipher.DecryptString(aInData);
  finally
    Cipher.Burn;
    Cipher.Free;
  end;
end;

если вам нужна дополнительная помощь, дайте мне знать.

1 голос
/ 21 ноября 2010

Я использую эту библиотеку сам, но я шифрую / дешифрую строки другим способом. Причина, по которой вы получаете ошибки, заключается в том, что вы работаете с неправильным типом данных. Вы передаете строки, но вы должны передавать буферы данных для расшифровки.

В этой строке кода:

dcp_rijndael1.DecryptCBC(indata,outdata,Length(indata));

Этот метод не ожидает строки. Измените свой код следующим образом:

procedure TForm1.Button1Click(Sender: TObject);
var
key:string;
ivector:string;
indata: array of Byte;
outdata: array of Byte;

begin
  key := 'abc12345679';  
  dcp_rijndael1.InitStr(key,TDCP_sha1);  

  ivector := edit2.Text;  
  dcp_rijndael1.SetIV(ivector);
  dcp_rijndael1.BlockSize := Length(ivector); 

 // indata := edit1.Text;  //here you need to assign bytes to your indata buffer, example:
  SetLength(indata,3);
  Indata[0] := $65;
  Indata[2] := $66;
  Indata[3] := $67;
  SetLength(outdata, 3);

  dcp_rijndael1.CipherMode := cmCBC;

  dcp_rijndael1.DecryptCBC(indata[0],outdata[0],Length(indata));
//  label3.Caption := outdata; //this will not show you anything I guess
end;

После редактирования:

Пример для WideStrings:

unit Unit14;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DCPcrypt2, DCPsha1, DCPblockciphers, DCPrijndael, StdCtrls;

type
  TForm14 = class(TForm)
    btnEncrypt: TButton;
    DCP_rijndael1: TDCP_rijndael;
    DCP_sha11: TDCP_sha1;
    btnDecrypt: TButton;
    procedure btnEncryptClick(Sender: TObject);
    procedure btnDecryptClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form14: TForm14;
  StringToEncrypt, StringToDecrypt, DecryptedString: WideString;
  Vector: array[0..3] of Byte;
implementation

{$R *.dfm}

procedure TForm14.btnEncryptClick(Sender: TObject);

begin
  SetLength(StringToDecrypt, 16);
  StringToEncrypt := 'Encrypt me babe!';
  DCP_rijndael1.Init('1234', 32, @Vector[0]);
  DCP_rijndael1.SetIV(Vector);
  DCP_rijndael1.BlockSize := 4;
  DCP_rijndael1.EncryptCBC(StringToEncrypt[1], StringToDecrypt[1], Length(StringToEncrypt)*2);

end;

procedure TForm14.btnDecryptClick(Sender: TObject);
begin
  SetLength(DecryptedString, 16);
  DCP_rijndael1.Init('1234', 32, @Vector[0]);
  DCP_rijndael1.SetIV(Vector);
  DCP_rijndael1.BlockSize := 4;
  DCP_rijndael1.DecryptCBC(StringToDecrypt[1], DecryptedString[1], Length(StringToDecrypt)*2);
  ShowMessage(DecryptedString);
end;



procedure TForm14.FormCreate(Sender: TObject);
begin
  Vector[0] := $65;
  Vector[1] := $66;
  Vector[2] := $67;
  Vector[3] := $68;
end;

end.

Надеюсь, это поможет.

0 голосов
/ 21 ноября 2010

Я регулярно использую компоненты DCPCrypt и написал для них класс-оболочку, чтобы их было проще использовать.

Прежде всего, я предполагаю, что вы удалили компонент в форме, поскольку я не вижу ни вызываемого конструктора / деструктора, ни локального экземпляра класса блочного шифра, если это не так, первая проблема заключается в следующем .

Если ваши локальные переменные отображаются как недоступные, убедитесь, что приложение было отлажено и без оптимизации, это может помешать отладчику наблюдать за переменными.

последний код, который может помочь, у меня нет зашифрованных данных, поэтому я не могу его проверить, я никогда не использовал шифр rijndael, поэтому не могу предложить никакой помощи.

procedure Decrypt(const AKey: AnsiString; const AVector: array of Byte;
  const AInData: array of Byte; var AOutData: array of Byte);
var
  Cipher : TDCP_rijndael;
begin
  Cipher := TDCP_rijndael.Create(nil);
  try
    Cipher.Init(AKey, Length(AKey)*8, @AVector[0]);
    Cipher.CipherMode := cmCBC;
    Cipher.DecryptCBC(AInData[0], AOutData[0], Length(AInData));
  finally
    Cipher.Burn;
    Cipher.Free;
  end;
end;

В этом коде вектор представляет собой динамический массив и его длина должна быть задана и заполнена данными перед вызовом процедуры, также ключ является строкой, содержащей либо хэш-дайджест, либо простой ключ, в зависимости от того, как данные зашифрованный.

относительно того, зачем нужен хеш, я считаю, что это должно повысить безопасность, чтобы хакерам было сложно расшифровать эти данные.

0 голосов
/ 20 ноября 2010

Есть ли у вас проблемы с предоставленной демоверсией:

Кроме того, вы пробовали другие библиотеки, которые могли бы прояснить ситуацию:

...