Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/file/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 加密大文件并添加到ZIP_C#_File_Encryption_Zip - Fatal编程技术网

C# 加密大文件并添加到ZIP

C# 加密大文件并添加到ZIP,c#,file,encryption,zip,C#,File,Encryption,Zip,我的目标是加密大型(cca 10 GB)输入文件,并将其附加到现有的System.IO.Packaging包中。我只能使用.NETFramework 3.5,不能使用第三方库 我尝试了十种方法,但没有成功。我尝试将输入读取到流,对其进行加密并保存到PackagePart。我尝试一个字节接一个字节地读取输入文件,然后对读取的字节进行加密,并将其从PackagePart附加到流中。每次我发现一个新问题(例如CryptoStream不支持查找等) 请告诉我正确的路好吗 //创建zip文件的方法(仅示例

我的目标是加密大型(cca 10 GB)输入文件,并将其附加到现有的System.IO.Packaging包中。我只能使用.NETFramework 3.5,不能使用第三方库

我尝试了十种方法,但没有成功。我尝试将输入读取到流,对其进行加密并保存到PackagePart。我尝试一个字节接一个字节地读取输入文件,然后对读取的字节进行加密,并将其从PackagePart附加到流中。每次我发现一个新问题(例如CryptoStream不支持查找等)

请告诉我正确的路好吗

//创建zip文件的方法(仅示例)
公共静态无效AppendToZip(SomeType encryptedData)
{
使用(Package zip=Package.Open(@“C:\myarchive.zip”,FileMode.OpenOrCreate))
{
uriuri=PackUriHelper.CreatePartUri(新Uri(“/files/test.enc”,UriKind.Relative));
尝试
{
part=zip.GetPart(uri);
}
接住
{
}
if(part==null)
{
part=zip.CreatePart(uri,“,CompressionOption.max);
}
使用(Stream dest=part.GetStream())
{
//如何将加密数据写入目标流?
}
}
}
//加密文件的示例方法
私有静态无效加密(字符串输入文件、字符串加密文件、字节[]密码字节、字节[]盐字节)
{
FileStream fsCrypt=newfilestream(cryptFile,FileMode.Create);
RijndaelManaged AES=新的RijndaelManaged();
AES.KeySize=256;
AES.BlockSize=128;
var key=新的Rfc2898DeriveBytes(passwordBytes,saltBytes,1000);
AES.Key=Key.GetBytes(AES.KeySize/8);
AES.IV=key.GetBytes(AES.BlockSize/8);
AES.Padding=PaddingMode.zero;
AES.Mode=CipherMode.CBC;
CryptoStream cs=新加密流(fsCrypt,AES.CreateEncryptor(),CryptoStreamMode.Write);
FileStream fsIn=newfilestream(inputFile,FileMode.Open);
int数据;
而((data=fsIn.ReadByte())!=-1)
{
cs.WriteByte((字节)数据);
}
fsIn.Close();
cs.Close();
fsCrypt.Close();
}

试试这个-利用块大小来提高性能。我用3.5 GB的ISO成功地做到了这一点。但是压缩加密内容的zip文件要大得多,所以正如另一个人所说,最好先压缩文件,然后再加密。但我不知道你的要求,所以这里是这个

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.IO.Packaging;

namespace ZipTest
{
    class Program
    {
        static void Main(string[] args)
        {
            // Block size we apply to all reads / writes
            const int BLOCK_SIZE = 65536;

            // The zip file we're using
            var zipFileName = @"C:\temp\ZipSO\MyZip.zip";

            // Password for encryption
            var password = "ThisIsMyPassword";

            // Name of temp file where we'll encrypt the file first
            var intermediateFile = @"C:\temp\ZipSO\Intermediate_" + Guid.NewGuid().ToString();

            // File we're encrypting / adding to archive
            var inputFile = @"C:\temp\ZipSO\InputFile.txt";

            // Salt for encryption
            var salt = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };

            // For the new / existing package part
            PackagePart part = null;

            // Open the archive
            using (var zip = Package.Open(zipFileName, System.IO.FileMode.OpenOrCreate))
            {
                // Uri for the part
                var uri = PackUriHelper.CreatePartUri(new Uri("/files/test.enc", UriKind.Relative));

                // Get existing part if found, or create new
                if (zip.PartExists(uri))
                    part = zip.GetPart(uri);
                else
                    part = zip.CreatePart(uri, "", CompressionOption.Maximum);

                // Encrypt the file first
                var passBytes = System.Text.Encoding.ASCII.GetBytes(password);
                using (var fs = new System.IO.FileStream(intermediateFile, System.IO.FileMode.OpenOrCreate, System.IO.FileAccess.Write))
                {
                    var key = new System.Security.Cryptography.Rfc2898DeriveBytes(passBytes, salt, 1000);
                    var keySize = 256;
                    var blockSize = 128;

                    var aes = new System.Security.Cryptography.RijndaelManaged()
                    {
                        KeySize = keySize,
                        BlockSize = blockSize,
                        Key = key.GetBytes(keySize / 8),
                        IV = key.GetBytes(blockSize / 8),
                        Padding = System.Security.Cryptography.PaddingMode.Zeros,
                        Mode = System.Security.Cryptography.CipherMode.CBC
                    };

                    using (var fsSource = new System.IO.FileStream(inputFile, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                    {
                        using (var cs = new System.Security.Cryptography.CryptoStream(fs, aes.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write))
                        {
                            var readBytes = new byte[BLOCK_SIZE];
                            int read;
                            while ((read = fsSource.Read(readBytes, 0, BLOCK_SIZE)) != 0)
                            {
                                cs.Write(readBytes, 0, read);
                            }
                            cs.Close();
                        }
                        fsSource.Close();
                    }
                    fs.Close();
                }

                // Now add it to the archive
                using (var p = part.GetStream(System.IO.FileMode.OpenOrCreate))
                {
                    using (var source = new System.IO.FileStream(intermediateFile, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                    using (var bw = new System.IO.BinaryWriter(p))
                    {
                        var readBytes = new byte[BLOCK_SIZE];
                        int read;
                        while ((read = source.Read(readBytes, 0, BLOCK_SIZE)) != 0)
                        {
                            bw.Write(readBytes.Take(read).ToArray());
                        }
                    }
                }

                // Clean up the intermediate
                System.IO.File.Delete(intermediateFile);
            }
        }
    }
}

压缩通常应该在加密之前完成,因为它通常可以获得更高的压缩比。(当然,这取决于数据类型。)显然这并不总是可能的,但可能对您来说是这样。那么您的目标是先加密文件,然后将其存储在zip中吗?您是使用zip进行存档还是压缩?两件事:-使用zip.PartExists而不是try-catch块-这样做成本不必要-一次1字节也很高-最好使用4096块并降低搅动,尤其是在查看10GB文件时。谢谢,Mark。我认为,在大多数情况下,这是最好的方法。但是有没有什么解决方案可以完全在内存中完成,而不需要临时文件呢?我相信你可以,但是内存成本会非常高。在这个场景中,我的页面文件在写入zip文件之间运行了大约500MB,正如我所提到的,对于3.8GB的ISO,它增长到了大约5GB。我不确定您正在加密/打包哪种数据,但我强烈建议您在文件流中使用辅助存储,而不是基于您所描述的内存流。在上面的场景中,您可以使用System.IO.MemoryStream替换可写文件流,但成本将非常高-并且您可能会面临缓冲区溢出的风险,这取决于您可以使用的内存。是否需要此操作的进一步信息,或者您是否同意我的回答?抱歉,我不在办公室,无法访问Internet。感谢您的时间,但这是我的目标-加载大文件并在内存中加密。我不想使用临时文件,因为这意味着我总共需要三个文件-第一个是原始文件,第二个是临时文件,第三个是输出文件。我的内存和磁盘空间有限。有什么办法吗?