Golang如何实现简单的文件加密与解密

来源:中国站长站作者:俊华头衔:草根站长
导读:本期聚焦于小伙伴创作的《Golang如何实现简单的文件加密与解密》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Golang如何实现简单的文件加密与解密》有用,将其分享出去将是对创作者最好的鼓励。

在Golang中实现简单的文件加密与解密,可以基于对称加密算法完成,其中AES算法因为安全性和性能的平衡,是常用的选择。下面将通过完整的代码示例,介绍从文件读取、加密处理到写入,再到解密还原的全流程实现。

Golang如何实现简单的文件加密与解密

核心依赖与加密原理

实现文件加密解密需要用到Golang标准库中的crypto/aes、crypto/cipher、io/ioutil等包。AES算法属于分组加密算法,需要将明文按固定分组长度处理,同时为了保证安全性,通常会结合随机生成的初始化向量IV使用。

加密的核心流程为:生成随机密钥和IV,读取原始文件内容,对内容进行AES加密,将IV和加密后的内容写入新文件。解密时则反向操作,先从加密文件中读取IV,再用密钥和IV解密内容,还原为原始文件。

完整实现代码

加密函数实现

下面是文件加密的具体实现代码,使用AES的CBC模式进行加密:

package main

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"fmt"
	"io"
	"os"
)

// EncryptFile 加密文件
// srcPath 原始文件路径,dstPath 加密后文件路径,key 加密密钥(长度需为16、24、32字节对应AES-128、AES-192、AES-256)
func EncryptFile(srcPath, dstPath string, key []byte) error {
	// 读取原始文件内容
	plaintext, err := os.ReadFile(srcPath)
	if err != nil {
		return fmt.Errorf("读取原始文件失败: %v", err)
	}

	// 创建AES块
	block, err := aes.NewCipher(key)
	if err != nil {
		return fmt.Errorf("创建AES块失败: %v", err)
	}

	// 生成随机的初始化向量IV,长度等于块大小
	iv := make([]byte, aes.BlockSize)
	if _, err := io.ReadFull(rand.Reader, iv); err != nil {
		return fmt.Errorf("生成IV失败: %v", err)
	}

	// 创建CBC模式加密器
	mode := cipher.NewCBCEncrypter(block, iv)

	// 对明文进行填充,保证长度是块大小的整数倍
	padding := aes.BlockSize - len(plaintext)%aes.BlockSize
	padtext := make([]byte, len(plaintext)+padding)
	copy(padtext, plaintext)
	for i := len(plaintext); i < len(padtext); i++ {
		padtext[i] = byte(padding)
	}

	// 加密数据
	ciphertext := make([]byte, len(padtext))
	mode.CryptBlocks(ciphertext, padtext)

	// 将IV和加密后的内容写入目标文件,前aes.BlockSize字节为IV
	dstFile, err := os.Create(dstPath)
	if err != nil {
		return fmt.Errorf("创建加密文件失败: %v", err)
	}
	defer dstFile.Close()

	if _, err := dstFile.Write(iv); err != nil {
		return fmt.Errorf("写入IV失败: %v", err)
	}
	if _, err := dstFile.Write(ciphertext); err != nil {
		return fmt.Errorf("写入加密内容失败: %v", err)
	}

	return nil
}

解密函数实现

对应的文件解密实现代码如下:

// DecryptFile 解密文件
// srcPath 加密文件路径,dstPath 解密后原始文件路径,key 解密密钥
func DecryptFile(srcPath, dstPath string, key []byte) error {
	// 读取加密文件内容
	encryptedData, err := os.ReadFile(srcPath)
	if err != nil {
		return fmt.Errorf("读取加密文件失败: %v", err)
	}

	// 校验加密文件长度是否合法
	if len(encryptedData) < aes.BlockSize {
		return fmt.Errorf("加密文件长度非法")
	}

	// 提取前aes.BlockSize字节作为IV
	iv := encryptedData[:aes.BlockSize]
	ciphertext := encryptedData[aes.BlockSize:]

	// 创建AES块
	block, err := aes.NewCipher(key)
	if err != nil {
		return fmt.Errorf("创建AES块失败: %v", err)
	}

	// 创建CBC模式解密器
	mode := cipher.NewCBCDecrypter(block, iv)

	// 解密数据
	plaintext := make([]byte, len(ciphertext))
	mode.CryptBlocks(plaintext, ciphertext)

	// 去除填充内容
	padding := int(plaintext[len(plaintext)-1])
	if padding > aes.BlockSize || padding == 0 {
		return fmt.Errorf("填充内容非法")
	}
	for i := len(plaintext) - padding; i < len(plaintext); i++ {
		if plaintext[i] != byte(padding) {
			return fmt.Errorf("填充内容校验失败")
		}
	}
	plaintext = plaintext[:len(plaintext)-padding]

	// 将解密后的内容写入目标文件
	if err := os.WriteFile(dstPath, plaintext, 0644); err != nil {
		return fmt.Errorf("写入解密文件失败: %v", err)
	}

	return nil
}

测试调用示例

可以通过下面的main函数测试加密解密功能:

func main() {
	// 密钥长度需要为16、24、32字节,对应不同的AES加密强度
	key := []byte("1234567890123456") // 16字节,AES-128

	// 加密文件
	err := EncryptFile("./test.txt", "./test_encrypted.bin", key)
	if err != nil {
		fmt.Printf("加密失败: %vn", err)
		return
	}
	fmt.Println("文件加密成功")

	// 解密文件
	err = DecryptFile("./test_encrypted.bin", "./test_decrypted.txt", key)
	if err != nil {
		fmt.Printf("解密失败: %vn", err)
		return
	}
	fmt.Println("文件解密成功")
}

注意事项

  • 密钥的安全管理非常重要,不要将密钥硬编码在代码中,生产环境建议使用密钥管理服务存储密钥。
  • AES的CBC模式需要随机IV,每次加密的IV都应该是随机生成的,IV不需要保密,但需要和加密内容一起存储。
  • 如果加密的文件体积较大,上面的实现会一次性读取全部内容到内存,可以改为流式读写的方式处理大文件,避免内存占用过高。
  • 解密时需要校验填充内容的合法性,避免解密被篡改的文件导致程序异常。

Golang文件加密文件解密AES加密修改时间:2026-06-20 08:51:30

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。