2016-10-13 1 views
-2

Je dois chiffrer une chaîne dans Delphi 7. La seule bibliothèque de chiffrement que j'ai réussi à exécuter est DCPCrypt.Chiffrer une chaîne dans Delphi 7 à l'aide de DCPCrypt (3DES)

j'ai étudié un exemple que les fichiers cryptés, et a essayé de l'adapter pour les chaînes, mais j'ai peur a lamentablement échoué ...

Ceci est ma fonction:

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; 

S'il vous plaît, ours à l'esprit que je suis complètement ignorant sur la façon dont le cryptage fonctionne. Je sais que vous ne cryptez pas de chaîne, mais des binaires, mais je ne sais pas comment traduire cela en code. Chaque fois que je l'exécute, j'obtiens un résultat différent (je suppose que c'est normal si vous utilisez des valeurs aléatoires), mais je ne sais pas si ça devrait être comme ça, puisque je dois l'envoyer à un autre serveur l'intégrité là-bas.

Thay m'a donné une fonction Java dans l'API, mais il est évident que je ne peut pas l'utiliser:

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; 
} 

je une bonne âme pouvait me donner un coup de main, je serais vraiment reconnaissant. Je me suis cogné la tête contre cela pendant plusieurs jours.

Merci d'avance.

+1

IMHO AES devrait être préféré 3DES ... Et notre [SynCrypto.pas] (https://github.com /synopse/mORMot/blob/master/SynCrypto.pas) L'unité Open Source fonctionne parfaitement avec Delphi 7. A partir de C#, avec le remplissage PKCS7, voir http://synopse.info/forum/viewtopic.php?id=3395 –

+1

@ ArnaudBouchez + . Exactement. 3DES n'est pas sûr depuis 20 ans .. –

+0

C'est génial, mais ce n'est pas vraiment mon appel (je dois adapter notre système pour un système de paiement en ligne). Je dois envoyer un formulaire en utilisant HMAC avec SHA256. Ils vous demandent de préparer un formulaire en JSON, de le coder en Base64, de préparer une clé unique de transaction, et d'ajouter une signature SHA256 basée sur le formulaire codé et la clé unique à la transaction. Cette clé est calculée en chiffrant avec 3DES notre mot de passe secret et l'identifiant de la transaction. C'est là que je suis coincé. – Tarrakis

Répondre

1

Cet exemple utilise la bibliothèque TLockBox Open Source pour crypter/décrypter une chaîne en utilisant 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. 
+0

Merci beaucoup, John. Je vais essayer lundi et je vous le ferai savoir. – Tarrakis

+0

Merci John, cela a fonctionné parfaitement! – Tarrakis

0

J'ai découvert plus tard que j'utilisais la fonction DCPcrypt mal comme guide. Je posterai l'autre je trouve, au cas où quelqu'un a besoin d'utiliser 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;