如何使用Golang实现文件加密与解密_Golang crypto包操作示例

发布时间 - 2026-01-29 00:00:00    点击率:
用 aes.Encrypt 加密文件前必须用 PKCS#7 填充明文至 16 字节整数倍,且每次加密需生成唯一 nonce(GCM)或 IV(CBC),并将其与密文一同写入文件头部。

aes.Encrypt 做文件加密前必须补全明文长度

Go 的 crypto/aes 只提供底层分组密码操作,不自动处理填充(padding)。直接对任意长度文件调用 aes.Encrypt 会 panic:「crypto/aes: invalid buffer size」。这是因为 AES 是块密码(block cipher),要求输入长度必须是 16 字节的整数倍。

常见做法是使用 PKCS#7 填充(注意:Go 标准库没内置,需手动实现):

func pkcs7Pad(data []byte, blockSize int) []byte {
    padding := blockSize - len(data)%blockSize
    padtext := make([]byte, padding)
    for i := range padtext {
        padtext[i] = byte(padding)
    }
    return append(data, padtext...)
}
  • 填充字节值等于填充长度(如缺 3 字节,则填 \x03\x03\x03
  • 即使原文长度刚好是 16 的倍数,也要额外填充一整块(16 个 \x10),否则解密时无法区分“末尾是真实数据还是填充”
  • 读取大文件时别一次性读进内存,应分块填充 + 加密,避免 OO

    M

crypto/cipher.BlockMode 的两种典型模式:CBC 和 GCM

CBC(Cipher Block Chaining)和 GCM(Galois/Counter Mode)是 Go 中最常用的两种封装方式。它们不是互斥选项,而是安全模型的根本差异:

  • cipher.NewCBCEncrypter 只提供机密性,**不校验完整性**;攻击者可篡改密文导致解密后乱码甚至执行恶意代码
  • cipher.NewGCM 同时提供加密与认证(AEAD),解密时自动验证 nonce + 密文未被篡改,失败直接返回 error
  • GCM 要求 nonce 绝对唯一(推荐用随机 12 字节),而 CBC 的 IV 只需不可预测(可用 crypto/rand.Read 生成)

生产环境强烈优先选 GCM。示例初始化:

block, _ := aes.NewCipher(key)
gcm, _ := cipher.NewGCM(block)
nonce := make([]byte, gcm.NonceSize())
rand.Read(nonce) // 注意:此处应检查 error

文件加密时,IV/nonce 和密钥绝不能硬编码或复用

ivnonce 写死在代码里,等于把锁芯图纸贴门上。同样,同一密钥加密多个文件时若重复使用 nonce(GCM)或 IV(CBC),会导致密文可被分析破解。

  • GCM 下重复 nonce:直接泄露明文异或结果,可能恢复出全部内容
  • CBC 下重复 IV:首块密文失去随机性,且相同明文首块产生相同密文,暴露结构
  • 正确做法:每次加密生成新随机 nonce(GCM)或 iv(CBC),并将其**和密文一起写入输出文件头部**(如前 12/16 字节),解密时先读出再使用
  • 密钥本身不应出现在代码中;建议用 KMS、环境变量(os.Getenv("ENC_KEY"))或派生函数(scrypt.Key)生成

解密失败时,gcm.Open 返回的 error 不含具体原因

gcm.Open(dst, nonce, ciphertext, additionalData) 在认证失败(如 nonce 错、密文被改、密钥不对)时统一返回 cipher: message authentication failed。它**故意不说明是哪部分出错**,防止侧信道泄露信息(比如通过 error 类型判断密钥是否正确)。

  • 不要靠 error 字符串做逻辑分支(如 strings.Contains(err.Error(), "authentication")
  • 确保传入的 nonce 长度等于 gcm.NonceSize()(通常是 12),否则会 panic
  • 如果解密后数据为空但无 error,检查是否误把密文当成了明文——GCM 输出不含原始 IV/nonce,你得自己从文件头剥离后再传给 Open

最常被忽略的是:加密时写入了 nonce,解密时却忘了读出来,直接拿整个文件当密文传给 gcm.Open,结果必然失败。


# go  # golang  # 编码  # app  # 字节  # ai  # 环境变量  # 标准库  # crypto  # 封装  # Error  # 字符串  # padding  # 两种  # 不含  # 只提供  # 的是  # 文件加密  # 成了  # 多个  # 整数倍  # 也要  # 出现在 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 详解vue.js组件化开发实践  uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)  如何在腾讯云服务器快速搭建个人网站?  小视频制作网站有哪些,有什么看国内小视频的网站,求推荐?  详解Nginx + Tomcat 反向代理 如何在高效的在一台服务器部署多个站点  google浏览器怎么清理缓存_谷歌浏览器清除缓存加速详细步骤  Laravel如何使用Telescope进行调试?(安装和使用教程)  如何正确选择百度移动适配建站域名?  历史网站制作软件,华为如何找回被删除的网站?  微信小程序 闭包写法详细介绍  如何在橙子建站中快速调整背景颜色?  Android 常见的图片加载框架详细介绍  网站制作软件有哪些,制图软件有哪些?  如何在云服务器上快速搭建个人网站?  Android中AutoCompleteTextView自动提示  JavaScript如何实现类型判断_typeof和instanceof有什么区别  Laravel如何配置中间件Middleware_Laravel自定义中间件拦截请求与权限校验【步骤】  网易LOFTER官网链接 老福特网页版登录地址  非常酷的网站设计制作软件,酷培ai教育官方网站?  如何在阿里云香港服务器快速搭建网站?  Laravel如何使用.env文件管理环境变量?(最佳实践)  如何破解联通资金短缺导致的基站建设难题?  网站制作免费,什么网站能看正片电影?  Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解  Laravel Octane如何提升性能_使用Laravel Octane加速你的应用  香港服务器选型指南:免备案配置与高效建站方案解析  Laravel怎么实现验证码(Captcha)功能  如何正确下载安装西数主机建站助手?  1688铺货到淘宝怎么操作 1688一键铺货到自己店铺详细步骤  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  如何打造高效商业网站?建站目的决定转化率  如何用JavaScript实现文本编辑器_光标和选区怎么处理  如何在IIS中配置站点IP、端口及主机头?  html5如何实现懒加载图片_ intersectionobserver api用法【教程】  如何在万网自助建站中设置域名及备案?  详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南  html如何与html链接_实现多个HTML页面互相链接【互相】  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  如何选择可靠的免备案建站服务器?  Laravel如何处理表单验证?(Requests代码示例)  潮流网站制作头像软件下载,适合母子的网名有哪些?  如何在万网主机上快速搭建网站?  Laravel中间件如何使用_Laravel自定义中间件实现权限控制  高端智能建站公司优选:品牌定制与SEO优化一站式服务  python中快速进行多个字符替换的方法小结  EditPlus中的正则表达式 实战(1)  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  如何在Windows服务器上快速搭建网站?