Go でパスワードが設定された zip ファイルを作成する

  • 1
    いいね
  • 0
    コメント

Go には標準zipファイルを扱うパッケージ archive/zip がありますが、パスワード付きzipファイルを作成する機能はありません1

そこで、パスワード付きの zip を作成する機能が追加されたフォークパッケージ yeka/zip を使います。

パスワード付き zip ファイルの作成

テキストファイル sample.txt をパスワード long-long-password を設定した zip ファイルを作成するサンプルコード。

package main

import (
    "bytes"
    "os"

    "github.com/yeka/zip"
)

func createZipBuffer() (*bytes.Buffer, error) {
    filename := "sample.txt"
    content := "ファイル内容"
    password := "long-long-password"

    buf := new(bytes.Buffer)
    w := zip.NewWriter(buf)

    // Create の代わりに Encrypt を使う
    f, err := w.Encrypt(filename, password, zip.AES256Encryption)
    if err != nil {
        return nil, err
    }

    _, err = f.Write([]byte(content))
    if err != nil {
        return nil, err
    }

    err = w.Close()
    if err != nil {
        return nil, err
    }

    return buf, nil
}

func main() {
    filename := "password.zip"
    f, err := os.Create(filename)
    if err != nil {
        panic(err)
    }
    defer f.Close()

    buf, err := createZipBuffer()
    if err != nil {
        panic(err)
    }

    if _, err := f.Write(buf.Bytes()); err != nil {
        panic(err)
    }
}

パスワード付き zip ファイルの読み込み

上記サンプルで作成したパスワード付き zip ファイルを読み込むサンプルコード。

package main

import (
    "bytes"
    "io"
    "io/ioutil"
    "os"

    "github.com/yeka/zip"
)

func readZipBuffer(buf *bytes.Reader) error {
    password := "long-long-password"

    zipr, err := zip.NewReader(buf, int64(buf.Len()))
    if err != nil {
        return err
    }

    for _, z := range zipr.File {
        z.SetPassword(password) // 解凍するためのパスワードを設定する
        rc, err := z.Open()
        if err != nil {
            return err
        }
        if _, err := io.Copy(os.Stdout, rc); err != nil {
            return err
        }
        rc.Close()
    }

    return nil
}

func main() {
    filename := "password.zip"
    f, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    defer f.Close()

    b, err := ioutil.ReadAll(f)
    if err != nil {
        panic(err)
    }

    if err := readZipBuffer(bytes.NewReader(b)); err != nil {
        panic(err)
    }
}

  1. github には対応要望の issue があるようです。