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
Zip Standard Encryption isn't actually secure. Unless you have to work with it, please use AES encryption instead.
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.
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()
}
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))
}
}