1

私は IV (初期化ベクトル) と鍵、および暗号文を持っています。暗号文を解読する必要があります。インターネットからDCPcrypt Cryptographic Component Library 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;

このコードでエラーが発生します。[ローカル変数] ウィンドウに、indata、outdata、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

4 に答える 4

1

私はこのライブラリを自分で使用していますが、別の方法で文字列を暗号化/復号化しています。エラーが発生する理由は、間違ったタイプのデータを操作しているためです。文字列を渡していますが、復号化するデータのバッファを渡す必要があります。

このコード行では:

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;

編集後:

ワイドストリングの例:

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.

お役に立てれば。

于 2010-11-20T23:32:08.807 に答える
0

私は 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;

このコードでは、ベクトルは動的配列であり、その長さを設定し、プロシージャを呼び出す前にデータを入力する必要があります。また、キーは、データが暗号化された方法に応じて、ハッシュ ダイジェストまたは単純なキーのいずれかを含む文字列です。

ハッシュが必要な理由については、セキュリティを強化して、ハッカーがそのデータを解読するのを困難にするためだと思います。

于 2010-11-20T23:30:34.437 に答える
0

彼らが提供したデモに問題がありますか?

また、問題を解決する可能性のある他のライブラリを試しましたか:

于 2010-11-20T20:45:54.813 に答える
0

前に投稿したコードに問題がある場合は、ストリームでこのバージョンを試してください。

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;

さらにヘルプが必要な場合はお知らせください。

于 2010-11-27T00:22:03.423 に答える