我有一个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;
这段代码给了我一个错误。 “Local Variables”窗口将indata,outdata,ivector,关键变量显示为“Inaccessible value”。 或许还有另一种方法可以做到这一点。不过,这似乎很简单。 提前谢谢。
在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编码)。 注意!加密文本长度与解密文本长度不同!
答案 0 :(得分: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;
修改后:
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.
希望这有帮助。
答案 1 :(得分:1)
如果您在使用我发布的代码时遇到问题,请尝试使用此流版本。
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;
如果您需要更多帮助,请告诉我。
答案 2 :(得分:0)
他们在提供的演示中遇到了一些问题:
另外,您是否尝试过其他可能清除问题的库:
答案 3 :(得分: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;
在此代码中,向量是一个动态数组,在调用过程之前应该设置其长度并填充数据,键也是一个包含哈希摘要或简单键的字符串,具体取决于数据的方式加密。
为什么需要哈希我相信它是为了提高安全性,以便黑客很难解密这些数据。