使用DCPCrypt(3DES)在Delphi 7中加密字符串

时间:2016-10-13 18:47:36

标签: delphi encryption delphi-7 3des

我需要在Delphi 7中加密字符串。我设法运行的唯一加密库是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;
}

我有任何善良的灵魂可以帮助我,我真的很感激。几天来,我一直在反对这一点。

提前致谢。

2 个答案:

答案 0 :(得分:1)

此示例使用Open Source TLockBox库使用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.

答案 1 :(得分:0)

后来我发现我使用错误的DCPCrypt功能作为指导。 如果有人需要使用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;