Page 1 of 1

Encrypting and Decrypting using SB

Posted: Sat 11 Feb 2017 23:31
by jbakuwel
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

Re: Encrypting and Decrypting using SB

Posted: Mon 13 Feb 2017 13:37
by ViktorV
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);

Re: Encrypting and Decrypting using SB

Posted: Tue 14 Feb 2017 01:04
by jbakuwel
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

Re: Encrypting and Decrypting using SB

Posted: Wed 15 Feb 2017 07:58
by jbakuwel
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

Re: Encrypting and Decrypting using SB

Posted: Wed 15 Feb 2017 08:41
by ViktorV
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

Re: Encrypting and Decrypting using SB

Posted: Wed 15 Feb 2017 21:42
by jbakuwel
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

Re: Encrypting and Decrypting using SB

Posted: Wed 03 May 2017 10:06
by Dimon
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.