C# 文件加密和解密带密码 生成ZIP SharpZipLib

2021-05-21  乐帮网


SharpZipLib(#ziplib,以前为NZipLib)是一个压缩库,它使用存储和压缩的压缩方法,PKZIP 2.0样式和AES加密,带有GNU长文件名扩展名的tar,GZip,zlib和原始的deflate以及BZip2来支持Zip文件。
不支持Deflate64,支持Zip64。 它实现为程序集(可在GAC中安装),因此可以轻松地并入其他项目(使用任何.NET语言)。 
下面就给一段使用SharpZipLib来压缩和解压文件夹,并使用加密技术。使用前请使用Nuget 搜索 SharpZipLib 并添加到项目中。

using System;
using System.IO;
using ICSharpCode.SharpZipLib.Core;
using ICSharpCode.SharpZipLib.Zip;

// Compresses the files in the nominated folder, and creates a zip file 
// on disk named as outPathname.
public void CreateSample(string outPathname, string password, string folderName) {

    using(FileStream fsOut = File.Create(outPathname))
    using(var zipStream = new ZipOutputStream(fsOut)) {

        //0-9, 9 being the highest level of compression

        // optional. Null is the same as not setting. Required if using AES.
        zipStream.Password = password;	

        // This setting will strip the leading part of the folder path in the entries, 
        // to make the entries relative to the starting folder.
        // To include the full path for each entry up to the drive root, assign to 0.
        int folderOffset = folderName.Length + (folderName.EndsWith("\\") ? 0 : 1);

        CompressFolder(folderName, zipStream, folderOffset);



// Recursively compresses a folder structure
private void CompressFolder(string path, ZipOutputStream zipStream, int folderOffset) {

    var files = Directory.GetFiles(path);

    foreach (var filename in files) {

        var fi = new FileInfo(filename);

        // Make the name in zip based on the folder
        var entryName = filename.Substring(folderOffset);

        // Remove drive from name and fix slash direction
        entryName = ZipEntry.CleanName(entryName); 

        var newEntry = new ZipEntry(entryName);

        // Note the zip format stores 2 second granularity
        newEntry.DateTime = fi.LastWriteTime; 

        // Specifying the AESKeySize triggers AES encryption. 
        // Allowable values are 0 (off), 128 or 256.
        // A password on the ZipOutputStream is required if using AES.
        //   newEntry.AESKeySize = 256;

        // To permit the zip to be unpacked by built-in extractor in WinXP and Server2003,
        // WinZip 8, Java, and other older code, you need to do one of the following: 
        // Specify UseZip64.Off, or set the Size.
        // If the file may be bigger than 4GB, or you do not need WinXP built-in compatibility, 
        // you do not need either, but the zip will be in Zip64 format which
        // not all utilities can understand.
        //   zipStream.UseZip64 = UseZip64.Off;
        newEntry.Size = fi.Length;


        // Zip the file in buffered chunks
        // the "using" will close the stream even if an exception occurs
        var buffer = new byte[4096];
        using (FileStream fsInput = File.OpenRead(filename)) {
            StreamUtils.Copy(fsInput, zipStream, buffer);

    // Recursively call CompressFolder on all folders in path
    var folders = Directory.GetDirectories(path);
    foreach (var folder in folders) {
        CompressFolder(folder, zipStream, folderOffset);

public void ExtractZipFile(string archivePath, string password, string outFolder) {

    using(var fsInput = File.OpenRead(archivePath)) 
    using(var zf = new ZipFile(fsInput)){
        if (!String.IsNullOrEmpty(password)) {
            // AES encrypted entries are handled automatically
            zf.Password = password;

        foreach (ZipEntry zipEntry in zf) {
            if (!zipEntry.IsFile) {
                // Ignore directories
            String entryFileName = zipEntry.Name;
            // to remove the folder from the entry:
            //entryFileName = Path.GetFileName(entryFileName);
            // Optionally match entrynames against a selection list here
            // to skip as desired.
            // The unpacked length is available in the zipEntry.Size property.

            // Manipulate the output filename here as desired.
            var fullZipToPath = Path.Combine(outFolder, entryFileName);
            var directoryName = Path.GetDirectoryName(fullZipToPath);
            if (directoryName.Length > 0) {

            // 4K is optimum
            var buffer = new byte[4096];

            // Unzip file in buffered chunks. This is just as fast as unpacking
            // to a buffer the full size of the file, but does not waste memory.
            // The "using" will close the stream even if an exception occurs.
            using(var zipStream = zf.GetInputStream(zipEntry))
            using (Stream fsOutput = File.Create(fullZipToPath)) {
                StreamUtils.Copy(zipStream, fsOutput , buffer);