千家信息网

怎么通过Golang编写一个AES加密解密工具

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容主要讲解"怎么通过Golang编写一个AES加密解密工具",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么通过Golang编写一个AES加密解密工
千家信息网最后更新 2026年10月31日怎么通过Golang编写一个AES加密解密工具

本篇内容主要讲解"怎么通过Golang编写一个AES加密解密工具",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么通过Golang编写一个AES加密解密工具"吧!

AES加密介绍及实现原理

AES( advanced encryption standard)使用相同密钥进行加密和解密,也就是对称加密。其他的对称加密如DES,由于DES密钥长度只有56位如今的算力甚至可以在5分钟内破解,而AES最高级别达到了256位密钥长度,如果采用穷举法,目前来看AES是一种"无法"被破解的加密存在。

AES用在哪里

如果你正在浏览本文,那么你就在使用AES(https协议中一部分使用了对称加密)。

  • 绿色上网:通过加密安全地连接到另一台搬石头砸脚的服务器。

  • 无线网络WIFI:和WAP2一起使用。

  • 应用程序:wechat、JD、Alipay等使用 AES 加密照片和消息或支付信息。

  • 存档和压缩工具:7z、WinZip 和 RAR。

  • 操作系统组件:一些操作系统组件(如文件系统)使用高级加密标准来确保安全性。

  • 编程语言库: Go、Python 和 C++ 等编码库实现了的AES加密(等会使用到)。

AES加密是如何实现的

参考:

what-is-the-aes-algorithm?

What is AES encryption and how does it work?

Block cipher mode of operation

从宏观上来看AES加密过程中的一轮(根据不同的密钥长度,轮数不一样,下面会说到)如下:

1.数据分块

首先把明文按照128bit拆分成若干个明文块(图上黄色块),一个字节包含 8 位,布局为 4×4矩阵(上图黄色部分),对最后一块填充至128bit,填充方式有PKCS7Padding(采用)/PKCS5Padding/ZeroPadding,无论咋填充最后解密时都要去除这些多余的填充。

2.密钥扩展

AES通过Rijndael's key schedule 将密钥被扩展为 (n+1) 个密钥,其中 n 是加密过程中要遵循的轮数。AES每个标准规定了所要加密的轮数,对于128位密钥,轮数是 10,要生成的密钥个数为 10+1,总共 11 个密钥。

标准密钥长度轮数分组长度
AES-128128位(16字节)10128位(16字节)
AES-192192位(24字节)12128位(16字节)
AES-256256位(32字节)14128位(16字节)

每一轮所要做的包括:字节替代(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)、加轮密钥(AddRoundKey)

3.字节替代(SubBytes)

每轮开始,首先进行SubBytes,字节根据预定义的 Rijndael S-box(可以简单认为是一个转换表)规定的规则进行替换。对a[i,j]中的每个字节进行一次转换后得到b[i,j]

4.行移位(ShiftRows)

对上一步得到矩阵进行ShiftRows,第一行不变,第二行移动1位,第三行2位,第四行3位。

5.列混淆(MixColumns)

再对矩阵的每一列和修补矩阵fixed matrix的二维常量数组做矩阵相乘,得到对应的输出列。

6.加轮密钥(AddRoundKey)

先将扩展密钥Kn排列成4×4矩阵,然后让输入数组的每一个字节a[i,j]与密钥对应位置的字节k[i,j]异或一次,得到输出b[i,j]。最后一轮不参与AddRoundKey

经过如上的10轮操作之后,得到了一个明文块的加密字符。解密则进行反向加密。

AES加密模式

ECB

在上面加密过程中每一个明文块都是独立进行加密的,简单且高效,但是如果一个段数据存在相关的明文块,则加密后的密文也会相同,对安全性也有一定影响。

CBC

CBC加密模式如下图所示,初始向量IV和明文异或,每个块的密文作为后续块的"向量",让每一个密文独一无二。我们待会采用这种模式。

Go实现AES加密工具scode

ok,上面大致了解AES加密是如何工作起来的,接下来通过Go中的crypto/aes和crypto/cipher包实现的AES加密解密工具。

PKCS7Padding将待补足字节数作为填充的字节

// pkcs7Padding 填充func pkcs7Padding(data []byte, blockSize int) []byte {    //判断缺少几位长度。最少1,最多 blockSize    padding := blockSize - len(data)%blockSize    //补足位数。把切片[]byte{byte(padding)}复制padding个    padText := bytes.Repeat([]byte{byte(padding)}, padding)    return append(data, padText...)}// pkcs7UnPadding 移除func pkcs7UnPadding(data []byte) ([]byte, error) {    length := len(data)    if length == 0 {        return nil, errors.New("加密字符串错误!")    }    //获取填充的个数    unPadding := int(data[length-1])    return data[:(length - unPadding)], nil}

使用 cipher的CBC模式对block加密和解密

// AesEncrypt 加密func AesEncrypt(data []byte, key []byte) ([]byte, error) {        // NewCipher creates and returns a new cipher.Block. The key argument should be the AES key, either 16, 24, or 32 bytes to select AES-128, AES-192, or AES-256.    block, err := aes.NewCipher(key)    if err != nil {        return nil, err    }    //判断加密快的大小    blockSize := block.BlockSize()    //填充    encryptBytes := pkcs7Padding(data, blockSize)    //初始化加密数据接收切片    crypted := make([]byte, len(encryptBytes))    //使用cbc加密模式    blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])    //执行加密    blockMode.CryptBlocks(crypted, encryptBytes)    return crypted, nil}// AesDecrypt 解密func AesDecrypt(data []byte, key []byte) ([]byte, error) {    block, err := aes.NewCipher(key)    if err != nil {        return nil, err    }    //获取块的大小    blockSize := block.BlockSize()    //使用cbc    blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])    //初始化解密数据接收切片    crypted := make([]byte, len(data))    //执行解密    blockMode.CryptBlocks(crypted, data)    //去填充    crypted, err = pkcs7UnPadding(crypted)    if err != nil {        return nil, err    }    return crypted, nil}

循环从文件中读取100mb源数据用于加密后将密文写入文件,解密则读取密文解密后将源数据写入文件。

func EncryptFile(fileName string) (err error) {    f, err := os.Open(fileName)    if err != nil {        fmt.Println("未找到文件")        return    }    defer f.Close()    fInfo, _ := f.Stat()    fLen := fInfo.Size()    fmt.Println("待处理文件大小:", fLen)    maxLen := 1024 * 1024 * 100 //100mb  每 100mb 进行加密一次    var forNum int64 = 0    getLen := fLen    if fLen > int64(maxLen) {        getLen = int64(maxLen)        forNum = fLen / int64(maxLen)        fmt.Println("需要加密次数:", forNum+1)    }    // encryptd to file    ff, err := os.OpenFile("en_"+fileName, os.O_RDWR|os.O_CREATE, 0666)    if err != nil {        fmt.Println("文件写入错误")        return err    }    defer ff.Close()    //循环加密,并写入文件    for i := 0; i < int(forNum+1); i++ {        a := make([]byte, getLen)        n, err := f.Read(a)        if err != nil {            fmt.Println("文件读取错误")            return err        }        getByte, err := EncryptByAes(a[:n])        if err != nil {            fmt.Println("加密错误")            return err        }        getBytes := append([]byte(getByte), []byte("\n")...)        //写入        buf := bufio.NewWriter(ff)        buf.WriteString(string(getBytes[:]))        buf.Flush()    }    ffInfo, _ := ff.Stat()    fmt.Printf("加密后文件为:%s,文件大小为:%v Byte \n", ffInfo.Name(), ffInfo.Size())    return nil}

参考:Golang实现AES加密和解密的示例代码

通过cobra添加命令后,创建命令的匿名函数

func(cmd *cobra.Command, args []string) {    copy(PwdKey, readPass())    Pwd := []byte("csgo!gogo")    if ByteSliceEqual(PwdKey, Pwd) {        //16字节key        PwdKey = append(PwdKey, 7, 3, 5, 5, 6, 0, 8)        if err := DecryptFile(args[0]); err != nil {            panic(err)        }    } else {        fmt.Println("密码错误")        os.Exit(1)    }}

使用方式看起来如下:

scode工具包含2个命令encode和decode,解密文件需要密码。

# ./scode  encode xpower.tar.gz待处理文件大小: 3397加密后文件为:en_xpower.tar.gz,文件大小为:4545 Byte# ./scode  decode en_xpower.tar.gzENTER PASSWORD: 密码错误# ./scode  decode en_xpower.tar.gzENTER PASSWORD: 待处理文件大小: 4545解密后文件为:de_en_xpower.tar.gz,文件大小为:3159 Byte

到此,相信大家对"怎么通过Golang编写一个AES加密解密工具"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

加密 文件 字节 密钥 大小 工具 数据 明文 矩阵 错误 长度 密文 模式 加密解密 安全 对称 命令 密码 标准 系统 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 为想互联网科技怎么样 朗涯互联网科技 上海喔噻互联网科技 亿人帮互联网科技 科技伦理 互联网公司 滨湖区互联网智能科技产品供应 蓝色互联网科技 哈尔滨新华互联网科技学院 中国科技互联网公司收入 浙江互联网科技研学营 朱啸虎曾投资哪些互联网科技企业 山东子淼互联网科技有限公司 工业互联网科技成果转化 广东鹅鹅鹅互联网科技有限公司 上海万顺科技互联网有限公司招聘 银川新华互联网科技学校是国营吗 互联网科技收购价值 互联网对科技影响 安徽九吞吴互联网科技有限公司 科技美学互联网 艺术 互联网科技开发公司 互联网科技视频 安徽鑫晟辉互联网科技 广西互联网科技公司 互联网科技热点资讯 湖南诚度互联网科技有限公司 互联网科技公司有风险吗 辽宁互联网新科技 企晟互联网信息科技有限公司 互联网科技公司营业执照怎么办理
0