You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DotNetZip加密仅生效于单个文件,求开源文件夹级加密压缩库

问题解决与库推荐

核心问题说明

你遇到的DotNetZip行为是正常的——它的全局密码设置仅作用于压缩包内的文件,而非压缩包本身或所谓的"主文件夹"。实际上标准ZIP格式本身不支持对"文件夹"单独加密,文件夹的加密效果依赖于其包含的文件全部被加密,或是部分库通过特殊逻辑模拟实现。

免费/开源库推荐

1. SharpZipLib (ICSharpCode.SharpZipLib)

这是.NET生态中最常用的开源ZIP处理库之一,完全免费且功能齐全。它支持设置全局密码加密所有添加的文件(含文件夹内的文件),也能为单个文件/文件夹单独配置密码。

代码示例(加密整个文件夹及内部所有内容):

using ICSharpCode.SharpZipLib.Zip;

// 初始化ZIP输出流
using (var fs = File.Create(zipFilePath))
using (var zipStream = new ZipOutputStream(fs))
{
    zipStream.SetLevel(9); // 设置压缩级别
    zipStream.Password = password; // 全局密码,所有条目将使用该密码加密

    // 添加目标文件夹及内部所有内容
    AddDirectoryToZip(folderToZip, zipStream, "");

    zipStream.Finish();
    zipStream.Close();
}

Console.WriteLine("文件夹已成功压缩并加密。");

// 递归添加文件夹的辅助方法
private static void AddDirectoryToZip(string directoryPath, ZipOutputStream zipStream, string parentFolder)
{
    var files = Directory.GetFiles(directoryPath);
    foreach (var file in files)
    {
        var entryName = Path.Combine(parentFolder, Path.GetFileName(file));
        var entry = new ZipEntry(entryName) { DateTime = DateTime.Now };
        zipStream.PutNextEntry(entry);

        using (var fileStream = File.OpenRead(file))
        {
            fileStream.CopyTo(zipStream);
        }
        zipStream.CloseEntry();
    }

    var subDirectories = Directory.GetDirectories(directoryPath);
    foreach (var subDir in subDirectories)
    {
        var subDirName = Path.Combine(parentFolder, Path.GetFileName(subDir));
        AddDirectoryToZip(subDir, zipStream, subDirName);
    }
}

2. System.IO.Compression(.NET内置库)

若使用.NET Core 3.0+或.NET 5+,内置的System.IO.Compression.ZipArchive配合扩展可实现密码加密。原生库本身不直接支持密码,需借助AES加密逻辑自定义实现,无需额外安装大型库,完全免费。

代码示例(通过AES加密实现文件夹加密):

using System.IO.Compression;
using System.Security.Cryptography;

// 创建加密的ZIP文件
using (var fs = new FileStream(zipFilePath, FileMode.Create))
using (var aes = Aes.Create())
{
    aes.Key = GenerateKey(password); // 从密码生成AES密钥
    aes.IV = new byte[16]; // 初始化向量

    // 写入加密头(需对应解压逻辑识别)
    fs.Write(aes.IV, 0, aes.IV.Length);

    using (var cryptoStream = new CryptoStream(fs, aes.CreateEncryptor(), CryptoStreamMode.Write))
    using (var archive = new ZipArchive(cryptoStream, ZipArchiveMode.Create))
    {
        // 添加文件夹及内部文件
        AddFolderToArchive(folderToZip, archive, "");
    }
}

Console.WriteLine("加密压缩完成。");

// 递归添加文件夹到ZipArchive的辅助方法
private static void AddFolderToArchive(string folderPath, ZipArchive archive, string entryPrefix)
{
    foreach (var file in Directory.GetFiles(folderPath))
    {
        var entryName = Path.Combine(entryPrefix, Path.GetFileName(file));
        var entry = archive.CreateEntry(entryName);
        using (var entryStream = entry.Open())
        using (var fileStream = File.OpenRead(file))
        {
            fileStream.CopyTo(entryStream);
        }
    }

    foreach (var subFolder in Directory.GetDirectories(folderPath))
    {
        var subFolderName = Path.Combine(entryPrefix, Path.GetFileName(subFolder));
        AddFolderToArchive(subFolder, archive, subFolderName);
    }
}

// 从密码生成AES密钥的辅助方法
private static byte[] GenerateKey(string password)
{
    var salt = new byte[16];
    using (var rng = RandomNumberGenerator.Create())
    {
        rng.GetBytes(salt);
    }
    var pbkdf2 = new Rfc2898DeriveBytes(password, salt, 10000);
    return pbkdf2.GetBytes(32); // 生成256位密钥
}

关于"压缩文件内文件夹设置密码"的说明

标准ZIP格式没有单独加密文件夹的概念,文件夹本质是目录条目,无实际内容。所有支持"文件夹加密"的库,本质逻辑都是:

  • 对该文件夹下的所有文件单独设置密码
  • 或通过加密文件夹元数据、隐藏目录条目模拟加密效果

SharpZipLib可实现对指定文件夹下的文件单独加密,只需在递归添加文件时,为目标文件夹的条目单独配置密码:

// 修改AddDirectoryToZip方法,针对特定文件夹设置专属密码
private static void AddDirectoryToZip(string directoryPath, ZipOutputStream zipStream, string parentFolder, string targetFolderPassword = null)
{
    var folderName = Path.GetFileName(directoryPath);
    bool isTargetFolder = string.Equals(folderName, "需要加密的文件夹名", StringComparison.OrdinalIgnoreCase);

    var files = Directory.GetFiles(directoryPath);
    foreach (var file in files)
    {
        var entryName = Path.Combine(parentFolder, folderName, Path.GetFileName(file));
        var entry = new ZipEntry(entryName) { DateTime = DateTime.Now };
        // 目标文件夹下的文件使用专属密码,其余使用全局密码
        entry.Password = isTargetFolder && !string.IsNullOrEmpty(targetFolderPassword) 
            ? targetFolderPassword 
            : zipStream.Password;
            
        zipStream.PutNextEntry(entry);

        using (var fileStream = File.OpenRead(file))
        {
            fileStream.CopyTo(zipStream);
        }
        zipStream.CloseEntry();
    }

    var subDirectories = Directory.GetDirectories(directoryPath);
    foreach (var subDir in subDirectories)
    {
        AddDirectoryToZip(subDir, zipStream, Path.Combine(parentFolder, folderName), targetFolderPassword);
    }
}

内容的提问来源于stack exchange,提问作者Srikant suryawanshi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 17:37:44