Golang 1.2:如何解压有密码保护的zip文件?

huangapple go评论144阅读模式
英文:

Golang 1.2: Unzip password protected zip file?

问题

你好!根据你的要求,我将为你翻译以下内容:

查看最新版本(1.2)的压缩包时,如何解压受密码保护的文件(使用7zip,AES-256编码)?我没有看到在哪里/如何添加这些信息。一个简单的示例将非常有帮助!

英文:

Looking at the latest release (1.2) zip package - how can I unzip a file that was password protected (using 7zip, AES-256 encoding)? I don't see where/how to add in that information. A simple example would be great!

答案1

得分: 4

archive/zip包似乎只提供基本的zip功能。我建议使用7zip和os/exec包来解压密码保护的zip文件。

在线的7-zip用户指南

了解7zip的最佳指南是7-zip.chm,它在Windows命令行的zip文件中可以找到,下载地址为http://www.7-zip.org/download.html

以下代码并不是最优的,但它展示了如何完成任务。

使用7zip解压密码保护的zip文件的代码

func extractZipWithPassword() {
	fmt.Printf("正在解压 `%s` 到目录 `%s`\n", zip_path, extract_path)
	commandString := fmt.Sprintf(`7za e %s -o%s -p"%s" -aoa`, zip_path, extract_path, zip_password)
	commandSlice := strings.Fields(commandString)
	fmt.Println(commandString)
	c := exec.Command(commandSlice[0], commandSlice[1:]...)
	e := c.Run()
	checkError(e)
}

示例程序

// 展示如何使用7zip解压密码加密的zip文件。
// 作者:Larry Battle <https://github.com/LarryBattle>
// 回答来自 http://stackoverflow.com/questions/20330210/golang-1-2-unzip-password-protected-zip-file
// 7-zip.chm - http://sevenzip.sourceforge.jp/chm/cmdline/switches/index.htm
// Effective Golang - http://golang.org/doc/effective_go.html
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var (
	txt_content     = "创建的示例文件。"
	txt_filename    = "name.txt"
	zip_filename    = "sample.zip"
	zip_password    = "42"
	zip_encryptType = "AES256"
	base_path       = "./"

	test_path          = filepath.Join(base_path, "test")
	src_path           = filepath.Join(test_path, "src")
	extract_path       = filepath.Join(test_path, "extracted")
	extracted_txt_path = filepath.Join(extract_path, txt_filename)
	txt_path           = filepath.Join(src_path, txt_filename)
	zip_path           = filepath.Join(src_path, zip_filename)
)
var txt_fileSize int64

func checkError(e error) {
	if e != nil {
		panic(e)
	}
}
func setupTestDir() {
	fmt.Printf("正在删除 `%s`\n", test_path)
	var e error
	os.Remove(test_path)
	fmt.Printf("正在创建 `%s`,`%s`\n", extract_path, src_path)
	e = os.MkdirAll(src_path, os.ModeDir|os.ModePerm)
	checkError(e)
	e = os.MkdirAll(extract_path, os.ModeDir|os.ModePerm)
	checkError(e)
}
func createSampleFile() {
	fmt.Println("正在创建", txt_path)
	file, e := os.Create(txt_path)
	checkError(e)
	defer file.Close()
	_, e = file.WriteString(txt_content)
	checkError(e)
	fi, e := file.Stat()
	txt_fileSize = fi.Size()
}
func createZipWithPassword() {
	fmt.Println("正在创建", zip_path)
	commandString := fmt.Sprintf(`7za a %s %s -p"%s" -mem=%s`, zip_path, txt_path, zip_password, zip_encryptType)
	commandSlice := strings.Fields(commandString)
	fmt.Println(commandString)
	c := exec.Command(commandSlice[0], commandSlice[1:]...)
	e := c.Run()
	checkError(e)
}
func extractZipWithPassword() {
	fmt.Printf("正在解压 `%s` 到目录 `%s`\n", zip_path, extract_path)
	commandString := fmt.Sprintf(`7za e %s -o%s -p"%s" -aoa`, zip_path, extract_path, zip_password)
	commandSlice := strings.Fields(commandString)
	fmt.Println(commandString)
	c := exec.Command(commandSlice[0], commandSlice[1:]...)
	e := c.Run()
	checkError(e)
}
func checkFor7Zip() {
	_, e := exec.LookPath("7za")
	if e != nil {
		fmt.Println("请确保已安装7zip并将其添加到环境变量中。")
	}
	checkError(e)
}
func checkExtractedFile() {
	fmt.Println("正在读取", extracted_txt_path)
	file, e := os.Open(extracted_txt_path)
	checkError(e)
	defer file.Close()
	buf := make([]byte, txt_fileSize)
	n, e := file.Read(buf)
	checkError(e)
	if !strings.Contains(string(buf[:n]), strings.Fields(txt_content)[0]) {
		panic(fmt.Sprintf("文件`%s`已损坏。\n", extracted_txt_path))
	}
}
func main() {
	fmt.Println("# 设置")
	checkFor7Zip()
	setupTestDir()
	createSampleFile()
	createZipWithPassword()
	fmt.Println("# 回答问题...")
	extractZipWithPassword()
	checkExtractedFile()
	fmt.Println("完成。")
}

输出

# 设置
正在删除 `test`
正在创建 `test/extracted`,`test/src`
正在创建 test/src/name.txt
正在创建 test/src/sample.zip
7za a test/src/sample.zip test/src/name.txt -p"42" -mem=AES256
# 回答问题...
正在解压 `test/src/sample.zip` 到目录 `test/extracted`
7za e test/src/sample.zip -otest/extracted -p"42" -aoa
正在读取 test/extracted/name.txt
完成。
英文:

The archive/zip package seems to only provide basic zip functionality.
I would use 7zip to unzip password protected zip files using the os/exec package.

Online 7-zip user guide

The best guide for understanding 7zip is 7-zip.chm, which is in the zip file for the windows command line.

The following code isn't optimal but it shows you how to get the job done.

Code for extracting a password protected zip using 7zip

func extractZipWithPassword() {
	fmt.Printf("Unzipping `%s` to directory `%s`\n", zip_path, extract_path)
	commandString := fmt.Sprintf(`7za e %s -o%s -p"%s" -aoa`, zip_path, extract_path, zip_password)
	commandSlice := strings.Fields(commandString)
	fmt.Println(commandString)
	c := exec.Command(commandSlice[0], commandSlice[1:]...)
	e := c.Run()
	checkError(e)
}

Example Program

// Shows how to extract an passsword encrypted zip file using 7zip.
// By Larry Battle <https://github.com/LarryBattle>
// Answer to http://stackoverflow.com/questions/20330210/golang-1-2-unzip-password-protected-zip-file
// 7-zip.chm - http://sevenzip.sourceforge.jp/chm/cmdline/switches/index.htm
// Effective Golang - http://golang.org/doc/effective_go.html
package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

var (
	txt_content     = "Sample file created."
	txt_filename    = "name.txt"
	zip_filename    = "sample.zip"
	zip_password    = "42"
	zip_encryptType = "AES256"
	base_path       = "./"

	test_path          = filepath.Join(base_path, "test")
	src_path           = filepath.Join(test_path, "src")
	extract_path       = filepath.Join(test_path, "extracted")
	extracted_txt_path = filepath.Join(extract_path, txt_filename)
	txt_path           = filepath.Join(src_path, txt_filename)
	zip_path           = filepath.Join(src_path, zip_filename)
)
var txt_fileSize int64

func checkError(e error) {
	if e != nil {
		panic(e)
	}
}
func setupTestDir() {
	fmt.Printf("Removing `%s`\n", test_path)
	var e error
	os.Remove(test_path)
	fmt.Printf("Creating `%s`,`%s`\n", extract_path, src_path)
	e = os.MkdirAll(src_path, os.ModeDir|os.ModePerm)
	checkError(e)
	e = os.MkdirAll(extract_path, os.ModeDir|os.ModePerm)
	checkError(e)
}
func createSampleFile() {
	fmt.Println("Creating", txt_path)
	file, e := os.Create(txt_path)
	checkError(e)
	defer file.Close()
	_, e = file.WriteString(txt_content)
	checkError(e)
	fi, e := file.Stat()
	txt_fileSize = fi.Size()
}
func createZipWithPassword() {
	fmt.Println("Creating", zip_path)
	commandString := fmt.Sprintf(`7za a %s %s -p"%s" -mem=%s`, zip_path, txt_path, zip_password, zip_encryptType)
	commandSlice := strings.Fields(commandString)
	fmt.Println(commandString)
	c := exec.Command(commandSlice[0], commandSlice[1:]...)
	e := c.Run()
	checkError(e)
}
func extractZipWithPassword() {
	fmt.Printf("Unzipping `%s` to directory `%s`\n", zip_path, extract_path)
	commandString := fmt.Sprintf(`7za e %s -o%s -p"%s" -aoa`, zip_path, extract_path, zip_password)
	commandSlice := strings.Fields(commandString)
	fmt.Println(commandString)
	c := exec.Command(commandSlice[0], commandSlice[1:]...)
	e := c.Run()
	checkError(e)
}
func checkFor7Zip() {
	_, e := exec.LookPath("7za")
	if e != nil {
		fmt.Println("Make sure 7zip is install and include your path.")
	}
	checkError(e)
}
func checkExtractedFile() {
	fmt.Println("Reading", extracted_txt_path)
	file, e := os.Open(extracted_txt_path)
	checkError(e)
	defer file.Close()
	buf := make([]byte, txt_fileSize)
	n, e := file.Read(buf)
	checkError(e)
	if !strings.Contains(string(buf[:n]), strings.Fields(txt_content)[0]) {
		panic(fmt.Sprintf("File`%s` is corrupted.\n", extracted_txt_path))
	}
}
func main() {
	fmt.Println("# Setup")
	checkFor7Zip()
	setupTestDir()
	createSampleFile()
	createZipWithPassword()
	fmt.Println("# Answer to question...")
	extractZipWithPassword()
	checkExtractedFile()
	fmt.Println("Done.")
}

Output

# Setup
Removing `test`
Creating `test/extracted`,`test/src`
Creating test/src/name.txt
Creating test/src/sample.zip
7za a test/src/sample.zip test/src/name.txt -p"42" -mem=AES256
# Answer to question...
Unzipping `test/src/sample.zip` to directory `test/extracted`
7za e test/src/sample.zip -otest/extracted -p"42" -aoa
Reading test/extracted/name.txt
Done.

答案2

得分: 2

https://github.com/yeka/zip 提供了提取密码保护的zip文件(AES和Zip标准加密,也称为ZipCrypto)的功能。

以下是如何使用它的示例代码:

package main

import (
	"os"
	"io"
	"github.com/yeka/zip"
)

func main() {
	file := "file.zip"
	password := "password"
	r, err := zip.OpenReader(file)
	if nil != err {
		panic(err)
	}
	defer r.Close()

	for _, f := range r.File {
		f.SetPassword(password)
		w, err := os.Create(f.Name)
		if nil != err {
			panic(err)
		}
		io.Copy(w, f)
		w.Close()
	}
}

这个工作是从 https://github.com/alexmullins/zip 分支出来的,它添加了对AES的支持。

英文:

https://github.com/yeka/zip provides functionality to extract password protected zip file (AES & Zip Standard Encryption aka ZipCrypto).

Below is an example how to use it:

package main

import (
	"os"
	"io"
	"github.com/yeka/zip"
)

func main() {
	file := "file.zip"
	password := "password"
	r, err := zip.OpenReader(file)
	if nil != err {
		panic(err)
	}
	defer r.Close()

	for _, f := range r.File {
		f.SetPassword(password)
		w, err := os.Create(f.Name)
		if nil != err {
			panic(err)
		}
		io.Copy(w, f)
		w.Close()
	}
}

The work is a fork from https://github.com/alexmullins/zip which add support for AES only.

答案3

得分: 1

如果其他人遇到提取失败并出现密码错误的情况,请尝试去掉引号。在我的情况下,引号被转义了,导致提取失败。

英文:

If anyone else runs into this the extraction failing with a password error, try removing the quotes. In my case they were being escaped by go and was causing the extraction to fail.

huangapple
  • 本文由 发表于 2013年12月2日 22:06:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/20330210.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定