我现在使用 using System.IO.Compression; 下面的方法利用DES+序列来进行文件夹的压缩;
现在我需要把这个压缩的文件加密。但是出现一个问题。如果不加密的话,文件的解压缩是正常的。但是加上加密以后,就会出现问题。
解密以后的文件,也加密之前的文件不同。所以无法解压缩了。不知道大家有没有碰到这样的事情。
1.压缩文件:5K
2.加密文件:5k
3.解密后的文件:10K
上面是操作时的文件大小变化,最后解密以后文件变大了。而且中文变成乱码了。要怎么解决?下面附上几个相关文件代码:

解决方案 »

  1.   

    zip.csusing System;
    using System.Data;
    using System.Configuration;
    using System.Collections;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.IO;
    using System.Runtime.InteropServices;public partial class export_zip : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            string path = Server.MapPath("export");
            path = path.Substring(0,path.Length-6);
            Gzip.Compress(path, path + "\\test.a_");        string key = FileEncryptDecrypt.GenerateKey();
            StreamWriter myWriter = new StreamWriter(path + "\\key.txt");
            myWriter.WriteLine(key);
            myWriter.Close();
            GCHandle gch = GCHandle.Alloc(key, GCHandleType.Pinned);
            FileEncryptDecrypt.EncryptFile(path + "\\test.a_", path + "\\aa.aa", key);
            FileEncryptDecrypt.ZeroMemory(gch.AddrOfPinnedObject(), key.Length*2);
            gch.Free();        StreamReader myreader = new StreamReader(path + "\\key.txt");
            string newKey = myreader.ReadLine();
            myreader.Close();        GCHandle gch2 = GCHandle.Alloc(newKey, GCHandleType.Pinned);
            FileEncryptDecrypt.DecryptFile(path + "\\aa.aa", path + "\\bb.a_", newKey);
            FileEncryptDecrypt.ZeroMemory(gch2.AddrOfPinnedObject(), newKey.Length * 2);
            gch2.Free();        if (key == newKey)
            {
                string abc = "";
            }        Gzip.DeCompress(path+"\\bb.a_",path + "\\kk\\");
        }
    }
      

  2.   

    FileEncryptDecrypt.csusing System;
    using System.IO;
    using System.Security;
    using System.Security.Cryptography;
    using System.Runtime.InteropServices;
    using System.Text;/// <summary>
    /// FileEncryptDecrypt 的摘要说明
    /// </summary>
    public class FileEncryptDecrypt
    {
        public FileEncryptDecrypt()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
        //  Call this function to remove the key from memory after use for security
        [System.Runtime.InteropServices.DllImport("KERNEL32.DLL", EntryPoint = "RtlZeroMemory")]
        public static extern bool ZeroMemory(IntPtr Destination, int Length);    // Function to Generate a 64 bits Key.
        public static string GenerateKey()
        {
            // Create an instance of Symetric Algorithm. Key and IV is generated automatically.
            DESCryptoServiceProvider desCrypto = (DESCryptoServiceProvider)DESCryptoServiceProvider.Create();        // Use the Automatically generated key for Encryption. 
            return ASCIIEncoding.ASCII.GetString(desCrypto.Key);
        }    public static void EncryptFile(string sInputFilename,string sOutputFilename,string sKey)
        {
            FileStream fsInput = new FileStream(sInputFilename,FileMode.Open,FileAccess.Read);        FileStream fsEncrypted = new FileStream(sOutputFilename,FileMode.Create,FileAccess.Write);
            DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
            DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
            ICryptoTransform desencrypt = DES.CreateEncryptor();
            CryptoStream cryptostream = new CryptoStream(fsEncrypted,desencrypt,CryptoStreamMode.Write);        byte[] bytearrayinput = new byte[fsInput.Length];
            fsInput.Read(bytearrayinput, 0, bytearrayinput.Length);
            cryptostream.Write(bytearrayinput, 0, bytearrayinput.Length);
            cryptostream.Close();
            fsInput.Close();
            fsEncrypted.Close();
        }    public static void DecryptFile(string sInputFilename,string sOutputFilename,string sKey)
        {
            DESCryptoServiceProvider DES = new DESCryptoServiceProvider();
            //A 64 bit key and IV is required for this provider.
            //Set secret key For DES algorithm.
            DES.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
            //Set initialization vector.
            DES.IV = ASCIIEncoding.ASCII.GetBytes(sKey);        //Create a file stream to read the encrypted file back.
            FileStream fsread = new FileStream(sInputFilename,FileMode.Open,FileAccess.Read);
            //Create a DES decryptor from the DES instance.
            ICryptoTransform desdecrypt = DES.CreateDecryptor();
            //Create crypto stream set to read and do a 
            //DES decryption transform on incoming bytes.
            CryptoStream cryptostreamDecr = new CryptoStream(fsread,desdecrypt,CryptoStreamMode.Read);
            //Print the contents of the decrypted file.
            StreamWriter fsDecrypted = new StreamWriter(sOutputFilename);
            fsDecrypted.Write(new StreamReader(cryptostreamDecr).ReadToEnd());
            fsDecrypted.Flush();
            fsDecrypted.Close();
        }    static void Main()
        {
            // Must be 64 bits, 8 bytes.
            // Distribute this key to the user who will decrypt this file.
            string sSecretKey;        // Get the Key for the file to Encrypt.
            sSecretKey = GenerateKey();        // For additional security Pin the key.
            GCHandle gch = GCHandle.Alloc(sSecretKey, GCHandleType.Pinned);        // Encrypt the file.        
            EncryptFile(@"C:\MyData.txt",
               @"C:\Encrypted.txt",
               sSecretKey);        // Decrypt the file.
            DecryptFile(@"C:\Encrypted.txt",
               @"C:\Decrypted.txt",
               sSecretKey);        // Remove the Key from memory. 
            ZeroMemory(gch.AddrOfPinnedObject(), sSecretKey.Length * 2);
            gch.Free();
        }}
    Gzip.cs
    using System;
    using System.Text;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Collections;
    using System.IO;
    using System.IO.Compression;/// <summary>
    /// Gzip 的摘要说明
    /// </summary>
    public class Gzip
    {
        public Gzip()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }
        /// <summary>
        /// 对目标文件夹进行压缩,将压缩结果保存为指定文件
        /// </summary>
        /// <param name="dirPath">目标文件夹</param>
        /// <param name="fileName">压缩文件</param>
        public static void Compress(string dirPath, string fileName)
        {
            ArrayList list = new ArrayList();
            foreach (string f in Directory.GetFiles(dirPath))
            {
                byte[] destBuffer = File.ReadAllBytes(f);
                SerializeFileInfo sfi = new SerializeFileInfo(f, destBuffer);
                list.Add(sfi);
            }
            IFormatter formatter = new BinaryFormatter();
            using (Stream s = new MemoryStream())
            {
                formatter.Serialize(s, list);
                s.Position = 0;
                CreateCompressFile(s, fileName);
            }
        }    /**/
        /// <summary>
        /// 对目标压缩文件解压缩,将内容解压缩到指定文件夹
        /// </summary>
        /// <param name="fileName">压缩文件</param>
        /// <param name="dirPath">解压缩目录</param>
        public static void DeCompress(string fileName, string dirPath)
        {
            using (Stream source = File.OpenRead(fileName))
            {
                using (Stream destination = new MemoryStream())
                {
                    using (GZipStream input = new GZipStream(source, CompressionMode.Decompress, true))
                    {
                        byte[] bytes = new byte[4096];
                        int n;
                        while ((n = input.Read(bytes, 0, bytes.Length)) != 0)
                        {
                            destination.Write(bytes, 0, n);
                        }
                    }
                    destination.Flush();
                    destination.Position = 0;
                    DeSerializeFiles(destination, dirPath);
                }
            }
        }    private static void DeSerializeFiles(Stream s, string dirPath)
        {
            BinaryFormatter b = new BinaryFormatter();
            ArrayList list = (ArrayList)b.Deserialize(s);        foreach (SerializeFileInfo f in list)
            {
                string newName = dirPath + Path.GetFileName(f.FileName);
                using (FileStream fs = new FileStream(newName, FileMode.Create, FileAccess.Write))
                {
                    fs.Write(f.FileBuffer, 0, f.FileBuffer.Length);
                    fs.Close();
                }
            }
        }    private static void CreateCompressFile(Stream source, string destinationName)
        {
            using (Stream destination = new FileStream(destinationName, FileMode.Create, FileAccess.Write))
            {
                using (GZipStream output = new GZipStream(destination, CompressionMode.Compress))
                {
                    byte[] bytes = new byte[4096];
                    int n;
                    while ((n = source.Read(bytes, 0, bytes.Length)) != 0)
                    {
                        output.Write(bytes, 0, n);
                    }
                }
            }
        }    [Serializable]
        class SerializeFileInfo
        {
            public SerializeFileInfo(string name, byte[] buffer)
            {
                fileName = name;
                fileBuffer = buffer;
            }        string fileName;
            public string FileName
            {
                get
                {
                    return fileName;
                }
            }        byte[] fileBuffer;
            public byte[] FileBuffer
            {
                get
                {
                    return fileBuffer;
                }
            }
        }}
      

  3.   

    如果觉得是中文的问题,转换成Unicode,再加密.
    注意一下字符的编码.
      

  4.   

    我产品代码的反汇编public static class ZipCrypto
    {
        // Fields
        private static byte[] cryptoIV = new byte[] { 2, 3, 1, 2, 0, 2, 3, 4 };
        private static byte[] cryptoKey = new byte[] { 2, 0, 0, 7, 1, 1, 0, 2 };
        private static DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        private static Encoding encoding = Encoding.UTF8;    // Methods
        private static ICryptoTransform CreateICryptoTransform(CryptoStreamMode mode)
        {
            if (mode == CryptoStreamMode.Read)
            {
                return des.CreateDecryptor(cryptoKey, cryptoIV);
            }
            return des.CreateEncryptor(cryptoKey, cryptoIV);
        }    public static string Read(string filename)
        {
            StreamReader reader = null;
            string CS$1$0000;
            try
            {
                FileStream file = new FileStream(filename, FileMode.Open, FileAccess.Read);
                CryptoStream crypto = new CryptoStream(file, CreateICryptoTransform(CryptoStreamMode.Read), CryptoStreamMode.Read);
                DeflateStream zip = new DeflateStream(crypto, CompressionMode.Decompress);
                reader = new StreamReader(zip, encoding);
                CS$1$0000 = reader.ReadToEnd();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }
            }
            return CS$1$0000;
        }    public static void Write(string filename, string data)
        {
            StreamWriter writer = null;
            try
            {
                FileStream file = new FileStream(filename, FileMode.Create, FileAccess.Write);
                CryptoStream crypto = new CryptoStream(file, CreateICryptoTransform(CryptoStreamMode.Write), CryptoStreamMode.Write);
                DeflateStream zip = new DeflateStream(crypto, CompressionMode.Compress);
                writer = new StreamWriter(zip, encoding);
                writer.Write(data);
                writer.Close();
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                if (writer != null)
                {
                    writer.Close();
                }
            }
        }
    }