Decrypting a file that has been encrypted twice

+1 vote
asked Jan 14, 2016 by Kucuk (140 points)
edited Jan 14, 2016 by Tomas Knopp

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
answered Jan 14, 2016 by Tomas Knopp (58,580 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.

commented Jan 14, 2016 by Kucuk (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.
commented Jan 14, 2016 by Tomas Knopp (58,580 points)
edited Jan 14, 2016 by Tomas Knopp
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.
commented Jan 14, 2016 by Kucuk (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?
commented Jan 14, 2016 by Tomas Knopp (58,580 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.
commented Jan 14, 2016 by Kucuk (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");
commented Jan 14, 2016 by Tomas Knopp (58,580 points)
edited Jan 27, 2016 by Tomas Knopp
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");
commented Jan 14, 2016 by Kucuk (140 points)
I see...

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

Thanks!
commented Jan 27, 2016 by Tomas Knopp (58,580 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!
commented Feb 15, 2016 by Tomas Knopp (58,580 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
answered Jan 19, 2016 by Kucuk (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);
commented Jan 19, 2016 by Tomas Knopp (58,580 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);
commented Jan 19, 2016 by Kucuk (140 points)
Oops, of course!

Thank you!
...