DelphiXe4. Encryption-decryption function file with WinCryptoApi. Encryption mode CBC. It seems to be working. Encrypts and decrypts.
// get winapi functions - http://msdn.microsoft.com/en-us/library/ms936171.aspx and ect..
procedure GuCryptFile(const SourceFileName, DestinationFileName, Password: tGuString; ToCrypt: TGuBoolean);
var
hProv, hKey, hHashP: TGuUlong;
Buffer: TguPByte;
len, aBufLen, CGuSoC, Mode, padMode: TGuDWord;
fsIn, fsOut: TGuStreamF;
k: TGuBoolean;
begin
CGuSoC:=SizeOf(TGuChar);hProv := 0;k := false; aBufLen := 0;
if not GuCryptAcquireContext(@hProv, nil, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, // Init crypto provider
CRYPT_VERIFYCONTEXT) then
MessageBox(0, 'Not CAC', 0, 0);
if not GuCryptCreateHash(hProv, CALG_MD2{MD5, SHA}, 0, 0, @hHashP) then // Create Hash
MessageBox(0, 'Not CCH', 0, 0);
if not GuCryptHashData(hHashP, @Password[1], Length(Password) * CGuSoC, 0) then // Get Hash
MessageBox(0, 'Not CHD', 0, 0);
if not GuCryptDeriveKey(hProv, CALG_RC4{RC2, AES}, hHashP, 0, @hKey) then // Init Key
MessageBox(0, 'Not CDK', 0, 0);
if not GuCryptDestroyHash(hHashP) then // Kill Hash
MessageBox(0, 'Not CDH', 0, 0);
// MessageBox(0, PChar(IntToStr(hprov)), 0, 0);
Mode := CRYPT_MODE_CBC;
if not GuCryptSetKeyParam(hKey, KP_MODE, @Mode, 0) then // Set CBC crypto mode
MessageBox(0, 'Not SKP', 0, 0);
if Mode <> CRYPT_MODE_CBC then // Check CBC mode
MessageBox(0, 'Not mCBC', 0, 0);
padMode := PKCS5_PADDING;
if not GuCryptSetKeyParam(hKey, KP_PADDING, @padMode, 0) then // Add PAdding
MessageBox(0, 'Not mPAD', 0, 0);
if not FileExists(SourceFileName) then
MessageBox(0, 'FNF', 0, 0);
if FileExists(DestinationFileName) then // Check files
DeleteFile(PChar(DestinationFileName));
if tocrypt then
if not GuCryptEncrypt(hKey, hHashP, true, 0, Nil, @aBufLen, 0) then // Get buflen if crypto mode
MessageBox(0, 'Not GBL', 0, 0);
fsIn := TFileStream.Create(SourceFileName, fmOpenRead); // open file for read
fsOut := TFileStream.Create(DestinationFileName, fmCreate); // open file for write
GetMem(Buffer, 512 + aBufLen); // get memory for buffer
repeat
len := fsIn.Read(Buffer^, 512); // read buffer
if len <> 512 then // check last bufffer
k := True;
if ToCrypt then
guCryptEncrypt(hkey, 0, k, 0, Buffer, @len, len + aBufLen) // crypt
else
guCryptDecrypt(hkey, 0, k, 0, Buffer, @len); // decrypt
fsOut.Write(Buffer^, len); // write buffer
until len <> 512; // check EOF
FreeMem(Buffer, 512+aBufLen); // free memory
fsIn.Free; // close file
fsOut.Free; // close file
if not GuCryptDestroyKey(hKey) then // kill key
MessageBox(0, 'Not CDK', 0, 0);
if hProv <> 0 then
if not GuCryptReleaseContext(hProv, 0) then // kill prov
MessageBox(0, 'Not CRC', 0, 0);
end;
Use
procedure TForm1.ButtonCryptClick(Sender: TObject);
begin
GuCryptFile('d:\1.txt', 'd:\1.xxx', 'mama mila ramu', True); // crypt file
end;
procedure TForm1.ButtonDeCryptClick(Sender: TObject);
begin
GuCryptFile('d:\1.xxx', 'd:\11.txt', 'mama mila ramu', False); // decrypt file
end;
Questions:
- As far as I understand it, involves the dependence of the CBC mode the next block from previous one. Test CBC: I encrypt file 1.txt (20 Kb), get 1.xxx. File 1.xxx open in HEX-editor and change it to 1 random byte. Decrypt 1.xxx, get 11.txt. Compare files: "Fc / b 1.txt 11.txt" (or just visually). I see that the transcript occurred in 11.txt changed only a few bytes in roughly the spot where changers in 1.txt. According to the rules after the place where I should not all transcribed. Right?
Especially install CBC mode and check it out, even though the description says that it is installed by default. Where is the mistake?
Now (Red squares - bad bytes):
Must:
Either way it should be?
Sorry for the bad English.