aes-gcm是当前最稳妥的默认选择,因其同时提供机密性与完整性认证,go标准库cipher.newgcm封装干净,避免cbc模式易出现的iv重用和缺乏完整性校验等问题。

加密算法选型:AES-GCM 是当前最稳妥的默认选择
Go 标准库 crypto/aes 和 crypto/cipher 支持 AES,但直接手写 CBC 模式容易出错(比如 IV 重用、缺少完整性校验)。生产环境应优先用 AES-GCM——它同时提供机密性和认证,且 Go 的 cipher.NewGCM 封装得足够干净。
- 避免用
crypto/des或crypto/rc4:已过时,标准库中甚至不推荐使用 - 别自己拼接 HMAC + AES-CBC:容易漏掉 padding 处理或 IV 随机性验证
-
AES-256-GCM密钥长度必须是 32 字节;若用户传入口令(password),需先用crypto/scrypt或crypto/bcrypt衍生密钥,不能直接当密钥用 - GCM 的 nonce(即 IV)长度固定为 12 字节;重复使用同一密钥+nonce 组合会导致密文完全可破解
加解密函数封装:一个可复用的 Encrypt / Decrypt 接口
不要把加解密逻辑散落在业务代码里。定义统一结构体封装 key、nonce 生成和错误处理:
type Crypto struct {
key []byte
}
func (c *Crypto) Encrypt(plaintext []byte) ([]byte, error) {
block, err := aes.NewCipher(c.key)
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonce := make([]byte, aesgcm.NonceSize())
if _, err = rand.Read(nonce); err != nil {
return nil, err
}
return aesgcm.Seal(nonce, nonce, plaintext, nil), nil
}
func (c *Crypto) Decrypt(ciphertext []byte) ([]byte, error) {
block, err := aes.NewCipher(c.key)
if err != nil {
return nil, err
}
aesgcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonceSize := aesgcm.NonceSize()
if len(ciphertext)
<p>注意:<code>Seal</code> 返回的字节切片包含 nonce + 加密数据;<code>Open</code> 会自动校验认证标签,失败时返回 <code>crypto/aes: decryption failed</code> 错误,不要忽略这个 error。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0"><img
src="https://img.php.cn/upload/manual/001/589/237/6a6ae8334dfb7907.jpg" alt="Go语言(Golang)1.26.0" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0" class="overflowclass">Go语言(Golang)1.26.0</a>
<p class="overflowclass">Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。</p>
</div>
<a rel="nofollow" href="/xiazai/gongju/2525" title="Go语言(Golang)1.26.0" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div>
<h3>密钥管理:别硬编码,也别依赖环境变量明文存储</h3>
<p>开发阶段可临时用 <code>os.Getenv("ENCRYPTION_KEY")</code>,但上线前必须替换。常见踩坑点:</p>
- 从文件读密钥时,确保文件权限为
0600(os.Chmod(path, 0600)),否则可能被其他用户读取 - 若用 KMS(如 AWS KMS、阿里云 KMS),Go 官方 SDK 提供
Decrypt和Encrypt方法,但注意 KMS 加密有 4KB 限制,大文件需用信封加密(Envelope Encryption):KMS 加密一个随机数据密钥,再用该密钥 AES 加密实际数据 - 测试时用固定密钥方便断言,但务必在
init()或TestMain中隔离,防止意外提交到仓库
边界场景验证:空数据、超长数据、篡改密文
加解密模块上线前必须覆盖三类典型异常:
- 加密空字节切片
[]byte{}:GCM 允许,但某些旧版客户端可能解析失败,建议业务层约定非空输入 - 加密 10MB+ 数据:GCM 本身无大小限制,但内存占用高;考虑分块加密(每块独立 nonce),或改用
crypto/cipher.Stream(如 AES-CTR),但需自行保证 nonce 唯一性 - 手动修改密文最后 1 字节再解密:应稳定返回
crypto/aes: decryption failed,而非 panic 或静默错误——这是 GCM 认证能力的核心价值,务必在单元测试中 assert 这个 error
密钥轮换、多版本密钥共存、密文格式迁移这些事,等第一版跑稳了再碰。一开始就把 nonce 生成、密钥加载、错误分类做扎实,后面才不会因为“加解密偶尔失败”花三天查不出原因。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










