ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

《Go Web 编程》9.6 加密与解密资料:base64、AES 与 DES 对称加密实战指南

2026/10/7 21:15:23 拓冰建站 浏览量
《Go Web 编程》9.6 加密与解密资料:base64、AES 与 DES 对称加密实战指南 文档教程【免费下载链接】build-web-application-with-golangA golang ebook intro how to build a web with golang项目地址https://gitcode.com/gh_mirrors/bu/build-web-application-with-golang点击查看免费下载导读本指南对应《Go Web 编程》build-web-application-with-golang第 9.6 节「加密和解密資料」聚焦于 Web 应用中最常见的对称加密需求当我们需要把敏感资料如支付凭证、接口令牌、密钥备份加密后持久化存储并在未来某个时刻按需解密还原时应选用对称加密算法。读完本文你将掌握 Go 语言中encoding/base64的简易加解密写法、crypto/aes与crypto/des高级对称加密套件的完整使用流程、cipher.Block接口的底层原理以及基于仓库英文版演进出的 AES-GCM 现代实践建议可直接落地到自己的 Web 服务中。base64 加解密最简单的资料变换方案如果 Web 应用足够简单对资料安全性没有严格要求可以采用一种实现成本最低的加解密方式——base64。它本质上是编码encoding而非加密encryption并不具备密钥任何人都能直接解码还原原文因此只适合用于「防肉眼直读」而非「防攻击者解密」的场景。Go 语言的encoding/base64标准包已经完整支持这一能力。下面是仓库中 zh-tw/09.6.md 提供的完整示例package main import ( encoding/base64 fmt ) func base64Encode(src []byte) []byte { return []byte(base64.StdEncoding.EncodeToString(src)) } func base64Decode(src []byte) ([]byte, error) { return base64.StdEncoding.DecodeString(string(src)) } func main() { // encode hello : 你好世界 hello world debyte : base64Encode([]byte(hello)) fmt.Println(debyte) // decode enbyte, err : base64Decode(debyte) if err ! nil { fmt.Println(err.Error()) } if hello ! string(enbyte) { fmt.Println(hello is not equal to enbyte) } fmt.Println(string(enbyte)) }运行该程序会先打印 base64 编码后的字符串随后打印还原后的原文。代码的关键点在于base64.StdEncoding.EncodeToString(src)将[]byte编码为标准 base64 字符串base64.StdEncoding.DecodeString(string(src))将 base64 字符串解码回[]byte解码可能失败输入不是合法 base64 时返回错误所以函数签名中必须携带error返回值编码与解码互为逆运算程序中用hello ! string(enbyte)的比对来验证还原正确性。如果你需要把编码结果放进 URL 查询参数、Cookie 或文件名中标准库还提供了更适合的变体base64.URLEncoding使用-与_代替与/避免 URL 转义问题、base64.RawStdEncoding与base64.RawURLEncoding去除末尾的填充符。它们的使用方式与StdEncoding完全一致只需替换对应的编码器常量。高级加解密Go crypto 家族的对称加密套件当业务对安全性的要求上升需要真正的密钥保护时应改用对称加密算法。Go 语言的crypto标准库中提供了两类主流的对称加密套件crypto/aes套件AESAdvanced Encryption Standard高级加密标准又称 Rijndael 加密法是美国联邦政府采用的区块加密标准也是当今事实上的对称加密主流选择crypto/des套件DESData Encryption Standard资料加密标准是一种对称加密标准曾是保护金融资料安全中使用最广泛的密钥系统也是美国联邦政府的旧加密标准但如今已被 AES 取代。由于这两种算法的使用方法高度相似都通过NewCipher创建分组密码、再配合分组模式进行流式加解密本节以crypto/aes为例完整演示。AES-CFB 完整示例加密与解密「我的名字是 Astaxie」仓库 zh-tw/09.6.md 给出的 AES 示例支持从命令行参数传入待加密资料与密钥便于直接运行验证package main import ( crypto/aes crypto/cipher fmt os ) var commonIV []byte{0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f} func main() { //需要去加密的字串 plaintext : []byte(My name is Astaxie) //如果傳入加密串的話plaint 就是傳入的字串 if len(os.Args) 1 { plaintext []byte(os.Args[1]) } //aes 的加密字串 key_text : astaxie12798akljzmknm.ahkjkljl;k if len(os.Args) 2 { key_text os.Args[2] } fmt.Println(len(key_text)) // 建立加密演算法 aes c, err : aes.NewCipher([]byte(key_text)) if err ! nil { fmt.Printf(Error: NewCipher(%d bytes) %s, len(key_text), err) os.Exit(-1) } //加密字串 cfb : cipher.NewCFBEncrypter(c, commonIV) ciphertext : make([]byte, len(plaintext)) cfb.XORKeyStream(ciphertext, plaintext) fmt.Printf(%s%x\n, plaintext, ciphertext) // 解密字串 cfbdec : cipher.NewCFBDecrypter(c, commonIV) plaintextCopy : make([]byte, len(plaintext)) cfbdec.XORKeyStream(plaintextCopy, ciphertext) fmt.Printf(%x%s\n, ciphertext, plaintextCopy) }这段代码的完整执行链路可以拆解为四步确定明文与密钥明文默认是My name is Astaxie密钥默认是astaxie12798akljzmknm.ahkjkljl;k均可用命令行参数覆盖go run main.go、go run main.go 你的明文、go run main.go 你的明文 你的密钥创建分组密码调用aes.NewCipher([]byte(key_text))校验密钥长度并生成cipher.Block密钥必须为 16、24 或 32 字节的[]byte分别对应AES-128、AES-192 或 AES-256三种算法强度长度不符会直接返回错误并被os.Exit(-1)终止加密用cipher.NewCFBEncrypter(c, commonIV)创建 CFB 模式的加密器再调用XORKeyStream将明文逐块异或为密文。注意 CFB 模式需要初始化向量commonIV示例中为 16 字节的全 0F 序列加密与解密必须使用同一个 IV才能正确还原解密用cipher.NewCFBDecrypter(c, commonIV)创建 CFB 模式解密器对同一段密文再次调用XORKeyStream得到还原后的明文。程序依次输出密钥长度、明文密文十六进制与密文十六进制明文可作为对称加密「加密—解密」闭环的最小可运行参考。cipher.Block 接口三个方法撑起加解密核心上面的示例中aes.NewCipher返回的是一个cipher.Block接口它定义了分组密码的基础能力。仓库文档完整给出了该接口的声明type Block interface { // BlockSize returns the ciphers block size. BlockSize() int // Encrypt encrypts the first block in src into dst. // Dst and src may point at the same memory. Encrypt(dst, src []byte) // Decrypt decrypts the first block in src into dst. // Dst and src may point at the same memory. Decrypt(dst, src []byte) }这三个方法的分工如下BlockSize() int返回分组的字节数AES 固定为 16 字节128 bitDES 为 8 字节这是选择初始化向量长度、判断密文对齐的依据Encrypt(dst, src []byte)加密第一个分组将src写入dstdst与src允许指向同一块内存原地操作Decrypt(dst, src []byte)解密第一个分组规则同上。需要注意的是Block接口本身只处理「单个分组」的加解密无法直接处理任意长度的连续资料流。因此实际项目中还要借助crypto/cipher包的分组模式——示例中的NewCFBEncrypter/NewCFBDecrypterCFB 密码反馈模式就是通过XORKeyStream把Block包装成可连续处理的流式密码。常用的同类包装还有 CBCNewCBCEncrypter、CTRNewCTREncrypter与 GCMNewGCM等模式可按吞吐量、是否需认证等需求选择。进阶建议优先采用 AES-GCM 认证加密仓库英文版文档 en/09.6.md 在演进中给出了更贴合现代安全实践的结论如果不确定自己在做什么除 GCM 模式Galois/Counter Mode伽罗瓦计数器模式的 AES 外不要使用其他任何方案。这一建议的缘由是CFB/CBC/CTR 等传统模式只提供机密性不提供完整性保护密文在传输或存储中被篡改时无法被察觉而 GCM 是一种认证加密AEAD模式在同一套运算中同时完成加密与消息认证密文被改动会被立即识别。仓库英文版配套的 AES-GCM 示例见 en/09.6.md 正文展示了推荐写法——使用随机 nonce 而非固定 IVfunc encrypt(plaintext []byte, key []byte) ([]byte, error) { c, err : aes.NewCipher(key) if err ! nil { return nil, err } gcm, err : cipher.NewGCM(c) if err ! nil { return nil, err } nonce : make([]byte, gcm.NonceSize()) if _, err io.ReadFull(rand.Reader, nonce); err ! nil { return nil, err } return gcm.Seal(nonce, nonce, plaintext, nil), nil } func decrypt(ciphertext []byte, key []byte) ([]byte, error) { c, err : aes.NewCipher(key) if err ! nil { return nil, err } gcm, err : cipher.NewGCM(c) if err ! nil { return nil, err } nonceSize : gcm.NonceSize() if len(ciphertext) nonceSize { return nil, errors.New(ciphertext too short) } nonce, ciphertext : ciphertext[:nonceSize], ciphertext[nonceSize:] return gcm.Open(nil, nonce, ciphertext, nil) }与 CFB 示例相比AES-GCM 写法有三个关键差异值得在实战中沿用nonce 随机生成nonce等价于 IV由rand.Reader每次随机产生不再使用硬编码的固定值避免相同密钥与相同 IV 重复使用导致的安全性退化nonce 与密文一起保存gcm.Seal(nonce, nonce, plaintext, nil)把 nonce 直接作为密文的前缀输出解密时用ciphertext[:nonceSize]切分取出因此无需额外管理 IV 的同步问题内置完整性校验gcm.Open在解密的同时验证认证标签密文被篡改或 nonce 不对应时会返回错误而decrypt中的errors.New(ciphertext too short)则先防御性地拦截过短输入。总结本小节围绕 Web 应用中「敏感资料加密存储、按需解密」的需求介绍了三种层次的加解密方案可以按业务对安全性的要求灵活选用base64实现最简单适合对安全性要求不高、仅需防直读的场景属于编码而非加密不具备密钥与保密性AES / DES 对称加密通过aes.NewCipher密钥必须为 16/24/32 字节对应 AES-128/192/256返回cipher.Block再配合 CFB 等分组模式完成任意长度资料的加密与解密适合常规敏感资料的落库保护AES-GCM 认证加密现代实践的推荐方案同时提供机密性与完整性校验nonce 随机生成并随密文存储可直接作为生产级实现的起点。需要说明的是本节的对称加密解决的是「加密后存储、按需解密」的问题若目标是「只验证、不解密」的密码存储则应采用上一节 9.5 存储密码 中介绍的加盐杂凑与 scrypt 方案。两种手段各司其职共同构成 Web 应用资料安全的基础防线。延伸阅读目录上一节存储密码下一节小结英文版 9.6 Encrypting and decrypting data含 AES-GCM 完整示例简体中文版9.6 加密和解密数据仓库配套示例代码目录en/code/src各章节可运行示例运行前请参考 en/code/readme.md 设置GOPATH赞分享文档教程【免费下载链接】build-web-application-with-golangA golang ebook intro how to build a web with golang项目地址https://gitcode.com/gh_mirrors/bu/build-web-application-with-golang点击查看免费下载相关推荐Go Web 应用中的数据加解密实战从 base64 编码到 AES/DES 对称加密build-web-application-with-golang 第 9.6 节Go Web 应用中的数据加解密实战从 base64 编码到 AES/DES 对称加密build web application with golang 第文档教程Go Web 应用对称加密实战用 crypto/aes 与 crypto/des 实现数据加解密build-web-application-with-golang 9.6Go Web 应用对称加密实战用 crypto/aes 与 crypto/des 实现数据加解密build web application with gol文档教程Go Web 编程中的数据加解密使用 crypto/aes 实现 AES-GCM 对称加密实战Go Web 编程中的数据加解密使用 crypto/aes 实现 AES GCM 对称加密实战 本文对应 build web application with文档教程上一篇TREK 自托管部署排障指南从会话 Cookie 到 MCP 集成的全链路问题排查下一篇developer-roadmap AI Engineer确定性评测Deterministic Evals规则化评估实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考