在 Go 语言中如何进行 AES-ECB-256 加解密

键盘旁的猫
键盘旁的猫
发布时间:2026-08-25 | 26人浏览过
原创

前言

在 Go 里做 AES 加解密并不难,难的是既要尽快写出可运行代码,又要保证和 PHP、Java 这类现有系统对得上。本文用一个现成开源库把 `AES-ECB-256` 的加密、解密过程走一遍,并把密钥长度、填充方式和 `base64` 编码这些最常见的出错点一并拆开说明。

AES 是常见的对称加密标准,Go 本身也能通过 crypto/aes 等标准库实现相关逻辑,但很多开发场景更关心的是:能不能尽快写出可用、并且方便和 PHP、Java 等语言互通的代码。下面就用一个开源库把 AES-ECB-256 的加密、解密流程拆开说明,同时把密钥长度、填充方式和输出编码这些容易踩坑的细节一并讲清楚。

为什么用库来做 AES-ECB-256

AES(高级加密标准)由美国国家标准与技术研究院(NIST)在 2001 年发布,用来取代更早期的 DES。它支持 128 位、192 位和 256 位密钥长度,在数据安全场景里使用非常广泛。

和 DES 相比,AES 的密钥长度更高。原文里提到,DES 的 56 位密钥在今天的算力条件下已经不够安全,因此很多实际项目会直接选用更高强度的 AES 方案。对 Go 开发者来说,问题往往不在于“能不能实现”,而在于“能不能少写样板代码,还能和其他语言保持一致”。

这里使用的开源库是 github.com/forgoer/openssl。它托管在 Github:https://github.com/forgoer/openssl,特点是调用简单,而且和 PHP、JAVA 等常见语言里的对应加密算法实现保持一致,适合做接口对接或历史系统兼容。

安装依赖

先通过 go get 安装依赖:

go get -u github.com/forgoer/openssl

如果你的项目本身已经使用 Go Modules,这一步执行后就可以直接在代码中引入 github.com/forgoer/openssl。

如何在 Go 中进行 AES-ECB-256 加密

使用这个库做加密时,核心调用基本就是一行:openssl.AesECBEncrypt。下面是原始示例:

AES-ECB-256 加密时密钥长度、填充方式和 base64 输出关系图
加密流程里的 3 个关键条件用卡片和箭头把加密流程中的三个关键条件串起来,方便读者快速核对参数是否正确。
package main

import (
    "encoding/base64"
    "fmt"
    "github.com/forgoer/openssl"
)

func main() {
    src := []byte("123456")
    key := []byte("12345678901234561234567890123456")
    dst, _ := openssl.AesECBEncrypt(src, key, openssl.PKCS7_PADDING)
    fmt.Println(base64.StdEncoding.EncodeToString(dst)) // x0h/7JbwjwWsiZMRoZvb9g==
}

这段代码里有几个关键点需要看明白:

1. 算法对应的是 32 位密钥

示例使用的是 AES-ECB-256,因此密钥长度必须是 32 位,也就是 256 bit。示例中的:

解密时先 base64 解码再 AES 解密的顺序示意图
解密顺序不要弄反这张图专门解释解密顺序,重点不是算法原理,而是避免把 base64 字符串直接丢进解密函数。
key := []byte("12345678901234561234567890123456")

正好是 32 个字符。如果长度不对,实际运行时就无法按 AES-256 正常处理。

2. 填充方式不能忽略

调用里传入了 openssl.PKCS7_PADDING,这表示使用 PKCS7 填充。只要明文长度不是分组长度的整数倍,就必须补齐;如果你要和其他语言互通,填充方式必须一致,否则即便密钥相同,结果也对不上。

3. 输出结果经过了 base64 编码

示例最终打印的不是原始密文字节,而是经过:

base64.StdEncoding.EncodeToString(dst)

处理后的字符串,输出结果为:

x0h/7JbwjwWsiZMRoZvb9g==

这点在跨语言对接时尤其重要。很多人看到对方系统传来一串字符串,就直接拿去解密,结果失败,问题往往不是 AES 本身,而是中间还隔着一层 base64 编码。

如何解密并还原明文

解密过程和加密对应,先把 base64 字符串还原成字节,再调用 openssl.AesECBDecrypt:

package main

import (
    "encoding/base64"
    "fmt"
    "github.com/forgoer/openssl"
)

func main() {
    key := []byte("12345678901234561234567890123456")
    data, _ := base64.StdEncoding.DecodeString("x0h/7JbwjwWsiZMRoZvb9g==")
    dst, _ := openssl.AesECBDecrypt(data, key, openssl.PKCS7_PADDING)
    fmt.Println(string(dst)) // 123456
}

这里的顺序不能颠倒:

先解码,再解密

"x0h/7JbwjwWsiZMRoZvb9g==" 是文本形式的密文展示结果,不是可以直接送进 AES 解密函数的原始字节。因此需要先执行:

data, _ := base64.StdEncoding.DecodeString("x0h/7JbwjwWsiZMRoZvb9g==")

得到真实密文字节后,才能继续解密。

密钥和填充方式要与加密端完全一致

解密端仍然使用同一个 32 位密钥,以及同样的 openssl.PKCS7_PADDING。只要其中任何一项不一致,输出就不会是原始明文 123456。

实际使用时最容易出错的地方

如果你是把这段代码接入现有系统,而不是单机演示,通常需要先检查下面几项:

密钥是否真的是 32 位

这里说的 32 位,示例按字符串长度理解就是 32 个字符。开发时最常见的问题是少一位、多一位,或者把看起来相同的值在不同编码下传来传去,最后导致长度不符。

双方是否都在使用 ECB 和 PKCS7

AES 只是算法名称,真正影响结果的还包括工作模式和填充方式。本文示例明确使用的是 AES-ECB-256 和 PKCS7_PADDING。如果对方系统实际用的是别的模式,结果就不会一致。

传输的是原始字节、base64,还是别的编码

示例中的密文展示是 base64 字符串。对接时一定要先确认对方给你的到底是什么格式,不要把“展示层字符串”和“真正参与解密的字节流”混为一谈。

小结

如果你只是想在 Go 里快速完成 AES-ECB-256 加解密,并且还要兼顾和 PHP、JAVA 等语言的兼容性,那么 github.com/forgoer/openssl 的确是一个上手成本很低的选择。按本文示例,记住三件事基本就够了:密钥长度是 32 位、填充方式使用 PKCS7_PADDING、密文展示通常经过 base64 编码。

除了 AES,这个库还支持 DES、RSA 等多种加解密方式。如果后续要扩展到其他算法,也可以沿着同一套调用方式继续处理。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表