Encrypting and Decrypting using SB

Discussion of open issues, suggestions and bugs regarding network security and data protection solution - SecureBridge
Post Reply
jbakuwel
Posts: 35
Joined: Tue 02 Feb 2010 04:47

Encrypting and Decrypting using SB

Post by jbakuwel » Sat 11 Feb 2017 23:31

Hi all,

SecureBridge 6.1.2

I'm having trouble encrypting & decryption a file using SB. Please see the code below.
After encrypting then decrypting the file, I get something close but not identical to the original file.
I also tried using a buffer specifically for encrypting/decrypting as the last buffer more often than not will only be partially filled by the FileStream.Read. If I use cryptBytes instead of inBytes, an exception is throw "Key not ready". Suggestions / recommendations welcome.

kind regards,
Jan

procedure TMain.Encrypt(const sFileName: string);
const
BUFSIZE = 245; // Emperically determined
var
ppKey: TScKey;
fsInput, fsOutput: TFileStream;
inBytes, outBytes, cryptBytes: TBytes;
iRead, iTotalRead: integer;
begin
iRead := 0;
ppKey := TScKey.Create(nil);
try
try
with ppKey do
begin
ImportFrom(edPublicKey.Text);
KeyName := 'PublicKey';
Ready := True;
end;

meLog.Lines.Add(Format('Encrypting %s using public key %s', [sFileName, edPublicKey.Text]));

fsInput := TFileStream.Create(sFileName, fmOpenRead);
fsOutput := TFileStream.Create(sFileName + '.enc', fmCreate);
SetLength (inBytes, BUFSIZE);

while fsInput.Position < fsInput.Size do
begin
iRead := fsInput.Read(inBytes, BUFSIZE); iTotalRead := iTotalRead + iRead;
//SetLength (cryptBytes, iRead);
//Move (inBytes, cryptBytes, iRead);
//outBytes := ppKey.Encrypt(cryptBytes); // this throws exception "Key not ready???"
outBytes := ppKey.Encrypt(inBytes);
fsOutput.Write(outBytes, Length(outBytes));
end;

meLog.Lines.Add(Format('Encrypt successful. In.S,P=(%d,%d), Out.S,P=(%d,%d). Read: %d',
[fsInput.Size, fsInput.Position, fsOutput.Size, fsOutput.Position, iTotalRead]));

except
on E: Exception do
begin
meLog.Lines.Add (Format('Encrypt unsuccessful: %s', [E.Message]));
end;

end;
finally
if Assigned(fsInput) then fsInput.Free;
if Assigned(fsOutput) then fsOutput.Free;
ppKey.Free;
end;
end;

procedure TMain.Decrypt(const sFileName: string);
const
BUFSIZE = 256; // Emperically determined
var
ppKey: TScKey;
fsInput, fsOutput: TFileStream;
inBytes, outBytes, cryptBytes: TBytes;
iRead, iTotalRead: integer;
begin
iRead := 0;
ppKey := TScKey.Create(nil);
try
try
with ppKey do
begin
ImportFrom(edPrivateKey.Text);
KeyName := 'PrivateKey';
Ready := True;
end;

meLog.Lines.Add(Format('Decrypting %s using private key %s', [sFileName, edPrivateKey.Text]));

fsInput := TFileStream.Create(sFileName, fmOpenRead);
fsOutput := TFileStream.Create(sFileName + '.dec', fmCreate);
SetLength (inBytes, BUFSIZE);

while fsInput.Position < fsInput.Size do
begin
iRead := fsInput.Read(inBytes, BUFSIZE); iTotalRead := iTotalRead + iRead;
//SetLength (cryptBytes, iRead);
//Move (inBytes, cryptBytes, iRead);
//outBytes := ppKey.Decrypt(cryptBytes);
outBytes := ppKey.Decrypt(inBytes);
fsOutput.Write(outBytes, Length(outBytes));
end;

meLog.Lines.Add(Format('Decrypt successful. In.S,P=(%d,%d), Out.S,P=(%d,%d). Bytes read: %d',
[fsInput.Size, fsInput.Position, fsOutput.Size, fsOutput.Position, iTotalRead]));
except
on E: Exception do
begin
meLog.Lines.Add (Format('Decrypt unsuccessful: %s', [E.Message]));
end;
end;

finally
fsInput.Free;
fsOutput.Free;
ppKey.Free;
end;

end;


Encrypting G:\Test\UUID.txt using public key G:\public.key
Encrypt successful. In.S,P=(1506,1506), Out.S,P=(1792,1792). Read: 1506

Decrypting G:\Test\UUID.txt.enc using private key G:\private.key
Decrypt successful. In.S,P=(1792,1792), Out.S,P=(1715,1715). Bytes read: 1792

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Encrypting and Decrypting using SB

Post by ViktorV » Mon 13 Feb 2017 13:37

To solve the issue, please in your sample change the following code:

Code: Select all

//SetLength (cryptBytes, iRead);
//Move (inBytes, cryptBytes, iRead);
//outBytes := ppKey.Encrypt(cryptBytes); // this throws exception "Key not ready???"
outBytes := ppKey.Encrypt(inBytes);
into

Code: Select all

SetLength (cryptBytes, iRead);
Move (inBytes[0], cryptBytes[0], iRead);
outBytes := ppKey.Encrypt(cryptBytes);

jbakuwel
Posts: 35
Joined: Tue 02 Feb 2010 04:47

Re: Encrypting and Decrypting using SB

Post by jbakuwel » Tue 14 Feb 2017 01:04

Hi Viktor,

Thanks for getting back to me. Unfortunately I'm still having issues.

When choosing an ENCRYPT_BUFFER size of 245 bytes and a DECRYPT_BUFFER size of 2048, which I had to empirically determine, I don't get exceptions that get thrown if I choose other (larger) buffer sizes (Bad Data, Bad Length etc) but still the decrypted file is not the same as the original file (not even in size) when I run the program on Windows. When I run the program on MacOS however, my test with a small file was successful. Now running it with a large file but that takes a very long time to complete. Will update this post once it's done.

I've made a small test program so you can easily reproduce the problem. You can download the source here:

https://drive.google.com/open?id=0B5a68 ... lZEMm1pZ1k

Also encryption/decryption is extremely slow (hardly usable this way). The CPUs are not really busy though... could this be due to the small buffer size? Encrypting or decrypting a 200MB file takes a very long time.

kind regards,
Jan

jbakuwel
Posts: 35
Joined: Tue 02 Feb 2010 04:47

Re: Encrypting and Decrypting using SB

Post by jbakuwel » Wed 15 Feb 2017 07:58

Hi Viktor,

The Mac ran all afternoon to encrypt, then decrypt a 250MB file. The good news is that the decrypted file was identical to the original file. In other words, this works correctly on a Mac. The bad news is that the exact same source code does not produce a correct result on Windows.

Hope you've been able to reproduce the issue with the example project.

kind regards,
Jan

ViktorV
Devart Team
Posts: 3168
Joined: Wed 30 Jul 2014 07:16

Re: Encrypting and Decrypting using SB

Post by ViktorV » Wed 15 Feb 2017 08:41

For encryption you use asymmetric encryption algorithm which is not designed to encrypt large amounts of data. When using this algorithm the number of encrypted data will significantly increase. To encrypt large amounts of data, symmetric cryptoalgorithms should be used.
We will add the possibility to encrypt/decrypt files in the next Securebridge release.You can follow the news about SecureBridge releases in the at https://www.devart.com/news

jbakuwel
Posts: 35
Joined: Tue 02 Feb 2010 04:47

Re: Encrypting and Decrypting using SB

Post by jbakuwel » Wed 15 Feb 2017 21:42

Hi Viktor,

My original test file is 258.998.272 bytes, the SecureBridge encrypted file (on MacOS) is 270.626.816, 4.2% larger, so not too bad really. The encrypted file produced on Windows has the same length but a different hash, presumably incorrect hash as decryption of the file on Windows doesn't produce the original file while it does do that on MacOS.

In my case I need asymmetrical encryption, symmetrical encryption unfortunately doesn't meet the requirements. To compare speed: gpg (on Linux) takes 14 seconds to encrypt this 250MB file using asymmetrical encryption with a 4096 bits RSA key and results in a smaller file too (246.311.477 bytes) vs SecureBridge requiring hours.

For small large files, the test program running on the Mac does produces a correct result albeit at a pace that renders it unusable. The same program running on Windows however does not produce a correct result, not even for a very small file. A few observations:

1. the encrypted small file produced on Windows has the same size as the one produced on MacOS but a different hash.
2. decrypting the encrypted file produced on Windows also on Windows produces a file that's way too small (and not identical to the original)
3. decrypting the encrypted file produced on MacOS on Windows produces the same incorrect result as in 2.

Could this be pointing to a problem with the Windows implementation? Should the buffer sizes be different on Windows compared to MacOS? If so can you please tell me what buffer sizes I should use on either platform (as well as on iOS and Android)?

Will a future version of SecureBridge support encrypting/decrypting files with asymmetric encryption or only symmetric encryption? Will it support Windows, MacOS, iOS and Android (and FreePascal/Linux)?

kind regards,
Jan

Dimon
Devart Team
Posts: 2910
Joined: Mon 05 Mar 2007 16:32

Re: Encrypting and Decrypting using SB

Post by Dimon » Wed 03 May 2017 10:06

jbakuwel wrote:My original test file is 258.998.272 bytes, the SecureBridge encrypted file (on MacOS) is 270.626.816, 4.2% larger, so not too bad really. The encrypted file produced on Windows has the same length but a different hash, presumably incorrect hash as decryption of the file on Windows doesn't produce the original file while it does do that on MacOS.
When encrypting the RSA algorithm uses a random initialization vector to improve encryption security, therefore when encrypting the same block the resulting data will be different each time.
jbakuwel wrote:Could this be pointing to a problem with the Windows implementation? Should the buffer sizes be different on Windows compared to MacOS? If so can you please tell me what buffer sizes I should use on either platform (as well as on iOS and Android)?
The maximum size of an encrypting block does not depend on operating system. Both on Windows and MacOS the maximum block size for PKCS2 padding mode (which can be specified in the Encrypt method) should be 11 bytes less than a key size, and for OAEP padding mode - 42 bytes less than a key size. When decrypting, you should pass block of the size equal to the key length in bytes.
jbakuwel wrote:In my case I need asymmetrical encryption, symmetrical encryption unfortunately doesn't meet the requirements.
Symmetric and asymmetric encryption keys have the same security degree when using keys of the appropriate length. You can read more here:
https://en.wikipedia.org/wiki/Key_size
https://www.keylength.com/en/4/
jbakuwel wrote:To compare speed: gpg (on Linux) takes 14 seconds to encrypt this 250MB file using asymmetrical encryption with a 4096 bits RSA key and results in a smaller file too (246.311.477 bytes) vs SecureBridge requiring hours.
The gpg program and others similar to it actually do not use asymmetric methods to encrypt data.
They work as follows:
1. generate a temporary random key for a symmetric encryption algorithm.
2. encrypt data using a symmetric encryption algorithm.
3. encrypt the generated temporary key with an asymmetric encryption algorithm and write it to the output block.
Thus, the speed is greatly increased by the use of a symmetric encryption algorithm.
jbakuwel wrote:Will a future version of SecureBridge support encrypting/decrypting files with asymmetric encryption or only symmetric encryption? Will it support Windows, MacOS, iOS and Android (and FreePascal/Linux)?
In the latest SecureBridge version (8.0.1), we supported the CMS protocol which implements the principle of encryption described above. This greatly increases encryption speed and security.
You can use the TScCMSProcessor component for encryption and signing data. This component is supported on all platforms.

Post Reply