Skip to content

edsongoncalves/zip

Repository files navigation

This fork add support for Standard Zip Encryption.

The work is based on https://github.com/alexmullins/zip

Available encryption:

zip.StandardEncryption
zip.AES128Encryption
zip.AES192Encryption
zip.AES256Encryption

Warning

Zip Standard Encryption isn't actually secure. Unless you have to work with it, please use AES encryption instead.

Performance defaults

When writing entries with Deflate, the writer automatically switches to Store for file types that are already compressed: .jpg, .jpeg, .png, .webp, .gif, .mp4, .mov, .mkv, .zip, .gz, .tgz, .tar.gz, .pdf, .jar, .war, .woff, and .woff2. Encrypted entries still keep their password/AES metadata; the writer only skips the Deflate compression step.

The built-in Deflate compressor now defaults to flate.BestSpeed, and still uses sync.Pool to reuse compressor instances. Use zip.SetDeflateLevel to choose another standard compress/flate level, or zip.SetCompressor(zip.Deflate, ...) to replace Deflate with a compatible alternative such as klauspost/compress/flate.

WinZip AES AE-2 entries skip CRC32 calculation while writing, because AES authentication covers integrity. The WinZip CTR buffer is 32 KiB to reduce per-block overhead.

For encrypted entries with a known uncompressed size, files up to 32 KiB are also stored. ZIP encryption still prepares keys per entry, so if you have thousands of tiny files and do not need them as separate ZIP entries, bundle them first and write the bundle as one encrypted entry.

Preparing entries in parallel should be done above Writer, because the final ZIP stream and central directory are still written sequentially by the format.

Example Encrypt Zip

package main

import (
	"bytes"
	"io"
	"log"
	"os"

	"github.com/yeka/zip"
)

func main() {
	contents := []byte("Hello World")
	fzip, err := os.Create(`./test.zip`)
	if err != nil {
		log.Fatalln(err)
	}
	zipw := zip.NewWriter(fzip)
	defer zipw.Close()
	w, err := zipw.Encrypt(`test.txt`, `golang`, zip.AES256Encryption)
	if err != nil {
		log.Fatal(err)
	}
	_, err = io.Copy(w, bytes.NewReader(contents))
	if err != nil {
		log.Fatal(err)
	}
	zipw.Flush()
}

Example Decrypt Zip

package main

import (
	"fmt"
	"io/ioutil"
	"log"

	"github.com/yeka/zip"
)

func main() {
	r, err := zip.OpenReader("encrypted.zip")
	if err != nil {
		log.Fatal(err)
	}
	defer r.Close()

	for _, f := range r.File {
		if f.IsEncrypted() {
			f.SetPassword("12345")
		}

		r, err := f.Open()
		if err != nil {
			log.Fatal(err)
		}

		buf, err := ioutil.ReadAll(r)
		if err != nil {
			log.Fatal(err)
		}
		defer r.Close()

		fmt.Printf("Size of %v: %v byte(s)\n", f.Name, len(buf))
	}
}

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages