使用 DCPCrypt (3DES) 加密 Delphi 7 中的字符串
Encrypt a string in Delphi 7 using DCPCrypt (3DES)
我需要在 Delphi 7 中加密一个字符串。我设法获得的唯一加密库 运行ning 是 DCPCrypt。
我研究了一个加密文件的例子,并尝试将其适配为字符串,但我恐怕失败得很惨......
这是我的功能:
function Encrypt3DES(psString, psKey: string): string;
var
lCipher:TDCP_3des;
CipherIV: array of byte; // the initialisation vector (for chaining modes)
lHash:TDCP_sha256;
lHashDigest: array of byte; // the result of hashing the passphrase with the salt
Salt: array[0..7] of byte; // a random salt to help prevent precomputated attacks
i:integer;
begin
lHash:=TDCP_sha256.Create(nil);
SetLength(lHashDigest,lHash.HashSize div 8);
for i := 0 to 7 do
Salt[i] := Random(256); // just fill the salt with random values (crypto secure PRNG would be better but not _really_ necessary)
//strmOutput.WriteBuffer(Salt,Sizeof(Salt)); // write out the salt so we can decrypt! ***I don't know what to do with this***
lHash.Init;
lHash.Update(Salt[0],Sizeof(Salt)); // hash the salt
lHash.UpdateStr(psKey); // and the passphrase
lHash.Final(lHashDigest[0]); // store the output in HashDigest
lCipher:=TDCP_3des.Create(nil);
//3DES is a block cipher, we need an initialisation vector
SetLength(CipherIV,TDCP_blockcipher(lCipher).BlockSize div 8);
for i := 0 to (Length(CipherIV) - 1) do
CipherIV[i] := Random(256); // again just random values for the IV
//strmOutput.WriteBuffer(CipherIV[0],Length(CipherIV)); // write out the IV so we can decrypt! ***I don't know what to do with this***
lCipher.Init(lHashDigest[0],TNeo.Min(lCipher.MaxKeySize,lHash.HashSize),CipherIV); // initialise the cipher with the hash as key
TDCP_blockcipher(lCipher).CipherMode := cmCBC; // use CBC chaining when encrypting
//lCipher.EncryptStream(strmInput,strmOutput,strmInput.Size); // encrypt the entire file
result:=lCipher.EncryptString(psString);
lCipher.Burn; // important! get rid of keying information
//strmInput.Free;
//strmOutput.Free;
end;
请记住,我完全不知道加密是如何工作的。我知道您不加密字符串,而是加密二进制文件,但我不知道如何将其转换为代码。
每次我 运行 它,我都会得到不同的结果(我想如果你使用随机值是正常的),但我不知道它是否应该那样,因为我必须将它发送到另一个服务器所以他们可以在那里检查完整性。
Thay在API中给了我一个Java函数,但显然我不能使用它:
public byte [] encrypt_3DES(final String claveHex, final String datos) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
byte [] ciphertext = null;
// Crea la clave
DESedeKeySpec desKeySpec = new DESedeKeySpec(toByteArray(claveHex));
SecretKey desKey = new SecretKeySpec(desKeySpec.getKey(), "DESede");
// Crea un cifrador
Cipher desCipher = Cipher.getInstance("DESede/CBC/NoPadding");
// Inicializa el cifrador para encriptar
desCipher.init(Cipher.ENCRYPT_MODE, desKey, new IvParameterSpec(IV));
// Se añaden los 0 en bytes necesarios para que sea un múltiplo de 8
int numeroCerosNecesarios = 8 - (datos.length() % 8);
if (numeroCerosNecesarios == 8) {
numeroCerosNecesarios = 0;
}
ByteArrayOutputStream array = new ByteArrayOutputStream();
array.write(datos.getBytes("UTF-8"), 0, datos.length());
for (int i = 0; i < numeroCerosNecesarios; i++) {
array.write(0);
}
byte [] cleartext = array.toByteArray();
// Encripta el texto
ciphertext = desCipher.doFinal(cleartext);
return ciphertext;
}
任何好心人都可以帮助我解决这个问题,我将不胜感激。这几天我一直在苦苦思索。
提前致谢。
此示例使用开源 TLockBox 库 encrypt/decrypt 使用 3DES 的字符串 https://sourceforge.net/p/tplockbox/wiki/Home/
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
//lockbox units
LbCipher, LbClass, LbAsym, LbRSA, LbString;
type
TForm1 = class(TForm)
edPlainText: TEdit;
edCipherText: TEdit;
btnEncryptString: TButton;
btnDescryptString: TButton;
procedure btnEncryptStringClick(Sender: TObject);
procedure btnDescryptStringClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Function TripleDesEncrypt(const APlaintext, APassphrase: String): String;
Var
Key128: TKey128;
begin
GenerateLMDKey(Key128, SizeOf(Key128), APassphrase);
result := TripleDESEncryptStringEx(APlainText, Key128, True);
End;
Function TripleDesDecrypt(const ACipherText, APassphrase: String): String;
Var
Key128: TKey128;
begin
GenerateLMDKey(Key128, SizeOf(Key128), APassphrase);
Try
result := TripleDESEncryptStringEx(ACipherText, Key128, False);
Except
Result := '';
End;
End;
procedure TForm1.btnEncryptStringClick(Sender: TObject);
begin
edCipherText.text := TripleDesEncrypt(edPlainText.Text, 'SecretPassphrase');
end;
procedure TForm1.btnDescryptStringClick(Sender: TObject);
begin
edPlainText.text := TripleDesDecrypt(edCipherText.text, 'SecretPassphrase');
end;
end.
后来我发现我使用了错误的 DCPCrypt 函数作为向导。
我会 post 我找到的另一个,以防有人需要使用 DCPCrypt:
function Encrypt3DES(psData, psKey: string): string;
var
Cipher: TDCP_3des;
begin
Cipher:= TDCP_3des.Create(nil);
Cipher.InitStr(psKey,TDCP_sha256); // initialize the cipher with a hash of the passphrase
result:=Cipher.EncryptString(psData);
Cipher.Burn;
Cipher.Free;
end;
我需要在 Delphi 7 中加密一个字符串。我设法获得的唯一加密库 运行ning 是 DCPCrypt。
我研究了一个加密文件的例子,并尝试将其适配为字符串,但我恐怕失败得很惨......
这是我的功能:
function Encrypt3DES(psString, psKey: string): string;
var
lCipher:TDCP_3des;
CipherIV: array of byte; // the initialisation vector (for chaining modes)
lHash:TDCP_sha256;
lHashDigest: array of byte; // the result of hashing the passphrase with the salt
Salt: array[0..7] of byte; // a random salt to help prevent precomputated attacks
i:integer;
begin
lHash:=TDCP_sha256.Create(nil);
SetLength(lHashDigest,lHash.HashSize div 8);
for i := 0 to 7 do
Salt[i] := Random(256); // just fill the salt with random values (crypto secure PRNG would be better but not _really_ necessary)
//strmOutput.WriteBuffer(Salt,Sizeof(Salt)); // write out the salt so we can decrypt! ***I don't know what to do with this***
lHash.Init;
lHash.Update(Salt[0],Sizeof(Salt)); // hash the salt
lHash.UpdateStr(psKey); // and the passphrase
lHash.Final(lHashDigest[0]); // store the output in HashDigest
lCipher:=TDCP_3des.Create(nil);
//3DES is a block cipher, we need an initialisation vector
SetLength(CipherIV,TDCP_blockcipher(lCipher).BlockSize div 8);
for i := 0 to (Length(CipherIV) - 1) do
CipherIV[i] := Random(256); // again just random values for the IV
//strmOutput.WriteBuffer(CipherIV[0],Length(CipherIV)); // write out the IV so we can decrypt! ***I don't know what to do with this***
lCipher.Init(lHashDigest[0],TNeo.Min(lCipher.MaxKeySize,lHash.HashSize),CipherIV); // initialise the cipher with the hash as key
TDCP_blockcipher(lCipher).CipherMode := cmCBC; // use CBC chaining when encrypting
//lCipher.EncryptStream(strmInput,strmOutput,strmInput.Size); // encrypt the entire file
result:=lCipher.EncryptString(psString);
lCipher.Burn; // important! get rid of keying information
//strmInput.Free;
//strmOutput.Free;
end;
请记住,我完全不知道加密是如何工作的。我知道您不加密字符串,而是加密二进制文件,但我不知道如何将其转换为代码。 每次我 运行 它,我都会得到不同的结果(我想如果你使用随机值是正常的),但我不知道它是否应该那样,因为我必须将它发送到另一个服务器所以他们可以在那里检查完整性。
Thay在API中给了我一个Java函数,但显然我不能使用它:
public byte [] encrypt_3DES(final String claveHex, final String datos) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
byte [] ciphertext = null;
// Crea la clave
DESedeKeySpec desKeySpec = new DESedeKeySpec(toByteArray(claveHex));
SecretKey desKey = new SecretKeySpec(desKeySpec.getKey(), "DESede");
// Crea un cifrador
Cipher desCipher = Cipher.getInstance("DESede/CBC/NoPadding");
// Inicializa el cifrador para encriptar
desCipher.init(Cipher.ENCRYPT_MODE, desKey, new IvParameterSpec(IV));
// Se añaden los 0 en bytes necesarios para que sea un múltiplo de 8
int numeroCerosNecesarios = 8 - (datos.length() % 8);
if (numeroCerosNecesarios == 8) {
numeroCerosNecesarios = 0;
}
ByteArrayOutputStream array = new ByteArrayOutputStream();
array.write(datos.getBytes("UTF-8"), 0, datos.length());
for (int i = 0; i < numeroCerosNecesarios; i++) {
array.write(0);
}
byte [] cleartext = array.toByteArray();
// Encripta el texto
ciphertext = desCipher.doFinal(cleartext);
return ciphertext;
}
任何好心人都可以帮助我解决这个问题,我将不胜感激。这几天我一直在苦苦思索。
提前致谢。
此示例使用开源 TLockBox 库 encrypt/decrypt 使用 3DES 的字符串 https://sourceforge.net/p/tplockbox/wiki/Home/
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,
//lockbox units
LbCipher, LbClass, LbAsym, LbRSA, LbString;
type
TForm1 = class(TForm)
edPlainText: TEdit;
edCipherText: TEdit;
btnEncryptString: TButton;
btnDescryptString: TButton;
procedure btnEncryptStringClick(Sender: TObject);
procedure btnDescryptStringClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Function TripleDesEncrypt(const APlaintext, APassphrase: String): String;
Var
Key128: TKey128;
begin
GenerateLMDKey(Key128, SizeOf(Key128), APassphrase);
result := TripleDESEncryptStringEx(APlainText, Key128, True);
End;
Function TripleDesDecrypt(const ACipherText, APassphrase: String): String;
Var
Key128: TKey128;
begin
GenerateLMDKey(Key128, SizeOf(Key128), APassphrase);
Try
result := TripleDESEncryptStringEx(ACipherText, Key128, False);
Except
Result := '';
End;
End;
procedure TForm1.btnEncryptStringClick(Sender: TObject);
begin
edCipherText.text := TripleDesEncrypt(edPlainText.Text, 'SecretPassphrase');
end;
procedure TForm1.btnDescryptStringClick(Sender: TObject);
begin
edPlainText.text := TripleDesDecrypt(edCipherText.text, 'SecretPassphrase');
end;
end.
后来我发现我使用了错误的 DCPCrypt 函数作为向导。 我会 post 我找到的另一个,以防有人需要使用 DCPCrypt:
function Encrypt3DES(psData, psKey: string): string;
var
Cipher: TDCP_3des;
begin
Cipher:= TDCP_3des.Create(nil);
Cipher.InitStr(psKey,TDCP_sha256); // initialize the cipher with a hash of the passphrase
result:=Cipher.EncryptString(psData);
Cipher.Burn;
Cipher.Free;
end;