+1 vote
by (140 points)
edited by

Hi,

Is it possible to encrypt a file, say with Twofish. Then again with AES.
It throws an exception. Any workarounds?

EDIT: The exception is thrown when decrypting the file.
EDIT by Rebex: see comments for code to decrypt the twice encrypted file.

2 Answers

+1 vote
by (58.9k points)

Hi,

with Rebex Security this is possible. Just apply the Encrypt method once again to the output of the previously encrypted file. This is a code sample that encrypts the file with TwoFish and then encrypts the TwoFish's output with AES:

// encrypt file with TwoFish
var encryption = new FileEncryption();
encryption.EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc;
encryption.SetPassword("secret password for twofish");
encryption.Encrypt("file.txt", "file.txt.enc");

// encrypt the encrypted file with AES - second layer
encryption.EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc;
encryption.SetPassword("secret password for aes");
encryption.Encrypt("file.txt.enc", "file.txt.enc.enc");

This is working just fine for me.

by (140 points)
Hi Tomas,

Thank you for your response.

That does indeed work, can you try decrypting the file again? It throws an exception that the file is corrupted.
by (58.9k points)
edited by
To decrypt the twice encrypted file, try this code:

            var decryption = new FileEncryption();
            decryption.EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc;
            decryption.SetPassword("secret password for aes");
            decryption.Decrypt("file.txt.enc.enc", "file.txt.enc");

            decryption.EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc;
            decryption.SetPassword("secret password for twofish");
            decryption.Decrypt("file.txt.enc", "file.txt");

This works for me just fine.
by (140 points)
I get the following exception:

An unhandled exception of type 'System.Security.Cryptography.CryptographicException' occurred in Rebex.Security.dll

Additional information: Invalid password or corrupt stream.


Any thoughts?
by (58.9k points)
Did you provide the correct password? When decrypting the file that was double encrypted with my code above, please make sure that you provide the good password for both. In fact you are unwrapping the first level of encryption and then the second. See my code for decrypting i provided in the comment above. Make sure the passwords do go in good order, so that you first decrypt the outer archive (with correct password)  and then the inner one.

if you are unable to find the problem please post the code you use for decrypting here and I'll be able to look into it.
by (140 points)
I use the same password for both encryptions. Please see my code below:

Encryption:
// encrypt file with TwoFish
            var encryption = new FileEncryption();
            encryption.EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc;
            encryption.SetPassword("DitIsEenHeleLangeKeyDatGeheimIsVoorIedereen!");
            encryption.Encrypt("mydata.txt", "mydata.txt.enc");

            // encrypt the encrypted file with AES - second layer
            encryption.EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc;
            //encryption.SetPassword("secret password for aes");
            encryption.Encrypt("mydata.txt.enc", "mydata.txt.enc.enc");


Decryption:
var decryption = new FileEncryption();
            decryption.EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc;
            decryption.SetPassword("DitIsEenHeleLangeKeyDatGeheimIsVoorIedereen!");
            decryption.Decrypt("mydata.txt.enc.enc", "decrypted.txt.dec"); //<---- Exception is occured here

            decryption.EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc;
            //decryption.SetPassword("secret password for twofish");
            decryption.Decrypt("decrypted.txt.dec", "decrypted.txt");
by (58.9k points)
edited by
It looks as though you stumbled across a bug in Rebex Security - thanks for the code snippet! The problem is that the component forgets the already set password when the encryption algorithm is changed before encrypting for the second time. I am opening a case for this issue and will report here once we have a solution.

UPDATE:
a fix will be released soon as part of the next release of Rebex components, e.g. 2016 R1.1.

Before we fix this issue, please call encryption.SetPassword() method after you change to AesCbc. This way a correct password will be used for the second encrypting layer and you will be able to decrypt it with the expected password.

Here is the code that works:

            string password = "DitIsEenHeleLangeKeyDatGeheimIsVoorIedereen!";

            // encrypt file with TwoFish
            var encryption = new FileEncryption();
            encryption.EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc;
            encryption.SetPassword(password);

            encryption.Encrypt("mydata.txt", "mydata.txt.enc");

            // encrypt the encrypted file with AES - second layer
            encryption.EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc;
            encryption.SetPassword(password); // please add this line as a workaround

            encryption.Encrypt("mydata.txt.enc", "mydata.txt.enc.enc");

            var decryption = new FileEncryption();
            decryption.EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc;
            decryption.SetPassword(password);
            decryption.Decrypt("mydata.txt.enc.enc", "decrypted.txt.dec");

            decryption.EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc;
            decryption.Decrypt("decrypted.txt.dec", "decrypted.txt");
by (140 points)
I see...

Setting the password with SetPassword again is indeed solving the problem.

Thanks!
by (58.9k points)
We have fixed this issue so that you will not have to call the SetPassword method when reusing the FileEncryption class after EncryptionAlgorithm has been changed.

The fix will be released as part of Rebex Security 2016 R1.1.

Once again thank you for your report!
by (58.9k points)
UPDATE: we fixed the issue and since release 2016 R1.1 the Encryption class can be reused with different algorithms without the need to re- set the password. See http://www.rebex.net/security.net/history.aspx#2016R1.1 for more details.
0 votes
by (140 points)
Can you see why the following code is not working?

Encrypting:
var file = "test.txt.plain";
            var password = "123";

            var cryptor = new FileEncryption { EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc };
            cryptor.SetPassword(password);
            cryptor.OverwriteExistingFile = true;
            cryptor.Encrypt(file, $"{file}.die");

            var cryptor2 = new FileEncryption { EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc };
            cryptor2.SetPassword(password);
            cryptor2.Encrypt($"{file}.die", file+".die2");

And then decrypting:
var password = "123";
            var file = "test.txt.plain";

            var cryptor = new FileEncryption
            {
                EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc,
                OverwriteExistingFile = true
            };
            cryptor.SetPassword(password);
            cryptor.Decrypt(file, $"{file}.dec"); //<-- EXCEPTION

            cryptor.EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc;
            cryptor.SetPassword(password);
            cryptor.Decrypt($"{file}.dec", file);
by (58.9k points)
Looking at your code I see that you are loading the plain text file and trying to decrypt it which results in an exception:

line  cryptor.Decrypt(file, $"{file}.dec");  // where I see that  file = "test.txt.plain"

Make sure you provide path of the encrypted file as the first argument of the FileEncryption.Decrypt method.

I fixed and simplified your code a bit and this is working:

            var file = "test.txt.plain";
            string fileSingleEncrypted = $"{file}.die1";
            string fileDoubleEncrypted = $"{file}.die2";

            var password = "set password to something safe";

            // encrypting

            var cryptor = new FileEncryption { EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc};
            cryptor.SetPassword(password);
            cryptor.Encrypt(file, fileSingleEncrypted);

            cryptor.EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc;
            cryptor.SetPassword(password);
            cryptor.Encrypt(fileSingleEncrypted, fileDoubleEncrypted);

            // decrypting

            var decryptor = new FileEncryption { EncryptionAlgorithm = FileEncryptionAlgorithm.TwofishCbc};
            decryptor.SetPassword("123");
            decryptor.Decrypt(fileDoubleEncrypted, fileSingleEncrypted);

            decryptor.EncryptionAlgorithm = FileEncryptionAlgorithm.AesCbc;
            decryptor.SetPassword(password);
            decryptor.Decrypt(fileSingleEncrypted, file);
by (140 points)
Oops, of course!

Thank you!
...