afero icon indicating copy to clipboard operation
afero copied to clipboard

zipfs with Password

Open wade-fs opened this issue 5 years ago • 1 comments

I am golang newbie, Could use github.com/alexmullins/zip(replace archive/zip) to support password in zip file?

I don't how to add SetPassword() . Could any one help? Thank you.

wade-fs avatar Jun 09 '20 09:06 wade-fs


package main

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

	"github.com/alexmullins/zip"
	"github.com/spf13/afero"
)

func main() {
	// Initialize Afero filesystem (MemFs for in-memory testing)
	fs := afero.NewMemFs()

	// Content to zip
	contents := []byte("Hello, World! This is a test file.")
	password := "golang123" // Password for encryption/decryption

	// Step 1: Create a password-protected ZIP file
	err := createPasswordProtectedZip(fs, "/test.zip", "hello.txt", contents, password)
	if err != nil {
		log.Fatalf("Failed to create ZIP: %v", err)
	}
	log.Println("Created password-protected ZIP: /test.zip")

	// Step 2: Read the password-protected ZIP file
	err = readPasswordProtectedZip(fs, "/test.zip", password)
	if err != nil {
		log.Fatalf("Failed to read ZIP: %v", err)
	}
	log.Println("Successfully read and decrypted ZIP")
}

// createPasswordProtectedZip creates a ZIP file with an encrypted file using Afero.
func createPasswordProtectedZip(fs afero.Fs, zipPath, fileName string, contents []byte, password string) error {
	// Create the ZIP file
	fzip, err := fs.Create(zipPath)
	if err != nil {
		return err
	}
	defer fzip.Close()

	// Initialize ZIP writer
	zipw := zip.NewWriter(fzip)
	defer zipw.Close()

	// Create an encrypted file entry
	w, err := zipw.Encrypt(fileName, password)
	if err != nil {
		return err
	}

	// Write contents to the encrypted file
	_, err = io.Copy(w, bytes.NewReader(contents))
	if err != nil {
		return err
	}

	// Flush and close the ZIP writer
	return zipw.Close()
}

// readPasswordProtectedZip reads and decrypts a ZIP file using Afero.
func readPasswordProtectedZip(fs afero.Fs, zipPath, password string) error {
	// Open the ZIP file
	fzip, err := fs.Open(zipPath)
	if err != nil {
		return err
	}
	defer fzip.Close()

	// Get file size for NewReader
	info, err := fzip.Stat()
	if err != nil {
		return err
	}

	// Create a buffer to hold ZIP contents
	buf := new(bytes.Buffer)
	_, err = io.Copy(buf, fzip)
	if err != nil {
		return err
	}

	// Initialize ZIP reader
	zipr, err := zip.NewReader(bytes.NewReader(buf.Bytes()), info.Size())
	if err != nil {
		return err
	}

	// Iterate through files in the ZIP
	for _, z := range zipr.File {
		// Set the password for decryption
		z.SetPassword(password)

		// Open the file
		rr, err := z.Open()
		if err != nil {
			return err
		}

		// Read and print contents
		content, err := io.ReadAll(rr)
		if err != nil {
			rr.Close()
			return err
		}
		rr.Close()

		log.Printf("Contents of %s: %s", z.Name, string(content))
	}

	return​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​

ljluestc avatar May 25 '25 11:05 ljluestc