Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encrypt an existing zip file

Tags:

c#

zip

encryption

I have an existing zip file, I want to use AESManaged class to encrypt it, but I don't find where I can set the password to the zip file in that class. After researching, I found some libaries such as 'DotNetZip' can complete the task. But my file is already a .zip, I needn't to compress again, I only want to encrypt it. Anyone can help me to use AESManaged class to ahieve the purpose?

Thanks

like image 871
James Avatar asked Sep 02 '25 11:09

James


2 Answers

I don't know if this is what your are looking for but I created a code that encrypts any file.

Here's the code for the encrypter:

private void EncryptFile(string inputFile, string outputFile)
        {
            string password = @"yourPWhere";
            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] key = CreateKey(password);

            string cryptFile = outputFile;
            FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create);

            RijndaelManaged RMCrypto = new RijndaelManaged();
            IV = CreateIV(password_mTxtBx.Text);

            CryptoStream cs = new CryptoStream(fsCrypt,
                RMCrypto.CreateEncryptor(key,IV),
                CryptoStreamMode.Write);

            FileStream fsIn = new FileStream(inputFile, FileMode.Open);

            int data;
            while ((data = fsIn.ReadByte()) != -1)
                cs.WriteByte((byte)data);


            fsIn.Close();
            cs.Close();
            fsCrypt.Close();
        }

Here's the code for the decrypter:

        private void DecryptFile(string inputFile, string outputFile)
    {
            string password = @"yourPWhere";

            UnicodeEncoding UE = new UnicodeEncoding();
            byte[] key = CreateKey(password);
            FileStream fsCrypt = new FileStream(inputFile, FileMode.Open);
            RijndaelManaged RMCrypto = new RijndaelManaged();
            IV = CreateIV(password_mTxtBx.Text);

            CryptoStream cs = new CryptoStream(fsCrypt,
                RMCrypto.CreateDecryptor(key, IV),
                CryptoStreamMode.Read);

            FileStream fsOut = new FileStream(outputFile.Remove(outputFile.Length - 4), FileMode.Create);

            int data;
            while ((data = cs.ReadByte()) != -1)
                fsOut.WriteByte((byte)data);

            fsOut.Close();
            cs.Close();
            fsCrypt.Close();

        }

I saw a similar code on codeproject a few months ago. So it's not directly my work. Credits go to the author.

Updated with password-based key derivation (PBKDF2):

private static int saltLengthLimit = 32;
private static byte[] GetSalt(int maximumSaltLength)
{
    var salt = new byte[maximumSaltLength];
    using (var random = new RNGCryptoServiceProvider())
    {
        random.GetNonZeroBytes(salt);
    }

    return salt;
}
public static byte[] CreateKey(string password)
{
    var salt = GetSalt(10);

    int iterationCount = 20000; // Nowadays you should use at least 10.000 iterations
    using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, iterationCount))
        return rfc2898DeriveBytes.GetBytes(16);
}

Creator for the IV (created from Password):

public byte[] CreateIV(string password)
{
    var salt = GetSalt(9);

    const int Iterations = 325;
    using (var rfc2898DeriveBytes = new Rfc2898DeriveBytes(password, salt, Iterations))
        return rfc2898DeriveBytes.GetBytes(16);
}

The byte length of the key is in my case 128bit(!) = 16 bytes (128/8), but you can use any other length supported by Rijndael (Key: 128, 192, 256 bit = 16, 24, 32 bytes). The IV is always 16 bytes!

like image 191
jAC Avatar answered Sep 03 '25 23:09

jAC


If you want to use a password in your original zip file when uncompressing, then you will need to re-compress the files and add a password when doing so.

This link from the dotnetzip library documentation shows an easy way to zip with password encryption using that library.


Additional note about security:
Don't use the zip 2.0 encryption method if you care at all about encryption security as it is quite flawed. Instead use the AES 256-bit encryption.

Here is some example code(pulled directly from the link above) showing an implementation of the AES 256-bit encryption using the dotnetzip library with default level compression:

using (ZipFile zip = new ZipFile())
{
    zip.AddFile("ReadMe.txt"); // no password for this one
    zip.Password= "Cool.Hand.Luke!";
    zip.Encryption= EncryptionAlgorithm.WinZipAes256;
    zip.AddFile("Rawdata-2008-12-18.csv");
    zip.Save("Backup-AES-Encrypted.zip");
}

Edit: added clarification about original zip file
Edit 2: added code

like image 25
Scott Lemmon Avatar answered Sep 03 '25 23:09

Scott Lemmon