Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Golang AES 加解密

Golang AES 加解密

作者头像
恋喵大鲤鱼
发布于 2022-05-09 03:15:54
发布于 2022-05-09 03:15:54
1.7K00
代码可运行
举报
文章被收录于专栏:C/C++基础C/C++基础
运行总次数:0
代码可运行

文章目录

AES 简介

利用 Go 提供的 AES 加解密与 Base64 编解码包,我们可以轻松实现 AES 加解密。实现之前,首先了解一下 AES 的基本知识。

AES(Advanced Encryption Standard)高级加密标准,是流行的对称加密算法,由美国国家标准与技术研究院(NIST)于 2001 年发布,用于取代 DES。Rijndael 算法 是 AES 标准的一个实现,一般说 AES 指的就是 Rijndael 算法。

(1)AES 有 5 种加密模式,分别是:

  • 电子密码本模式(ECB,Electronic Code Book);
  • 加密块链模式(CBC,Cipher Block Chaining),如果明文长度不是分组长度 16 字节的整数倍需要进行填充;
  • 计数模式(CTR,Counter);
  • 密码反馈模式(CFB,Cipher FeedBack);
  • 输出反馈模式(OFB,Output FeedBack)。

(2)AES 是对称分组加密算法,每组长度为 128bits,即 16 字节。

(3)AES 秘钥的长度只能是16、24 或 32 字节,分别对应三种加密模式 AES-128、AES-192 和 AES-256,三者的区别是加密轮数不同。

AES

分组长度(字节)

密钥长度(字节)

加密轮数

AES-128

16

16

10

AES-192

16

24

12

AES-256

16

32

14

AES 加解密实现

下面以 CBC 模式为例,实现 AES 加解密。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package main

import (
    "fmt"
    "crypto/cipher"
    "crypto/aes"
    "bytes"
    "encoding/base64"
)

// PKCS7Padding fills plaintext as an integral multiple of the block length
func PKCS7Padding(p []byte, blockSize int) []byte {
	pad := blockSize - len(p)%blockSize
	padtext := bytes.Repeat([]byte{byte(pad)}, pad)
	return append(p, padtext...)
}

// PKCS7UnPadding removes padding data from the tail of plaintext
func PKCS7UnPadding(p []byte) []byte {
	length := len(p)
	paddLen := int(p[length-1])
	return p[:(length - paddLen)]
}

// AESCBCEncrypt encrypts data with AES algorithm in CBC mode
// Note that key length must be 16, 24 or 32 bytes to select AES-128, AES-192, or AES-256
// Note that AES block size is 16 bytes
func AESCBCEncrypt(p, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	p = PKCS7Padding(p, block.BlockSize())
	ciphertext := make([]byte, len(p))
	blockMode := cipher.NewCBCEncrypter(block, key[:block.BlockSize()])
	blockMode.CryptBlocks(ciphertext, p)
	return ciphertext, nil
}

// AESCBCDecrypt decrypts cipher text with AES algorithm in CBC mode
// Note that key length must be 16, 24 or 32 bytes to select AES-128, AES-192, or AES-256
// Note that AES block size is 16 bytes
func AESCBCDecrypt(c, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}

	plaintext := make([]byte, len(c))
	blockMode := cipher.NewCBCDecrypter(block, key[:block.BlockSize()])
	blockMode.CryptBlocks(plaintext, c)
	return PKCS7UnPadding(plaintext)
}

// Base64AESCBCEncrypt encrypts data with AES algorithm in CBC mode and encoded by base64
func Base64AESCBCEncrypt(p, key []byte) (string, error) {
	c, err := AESCBCEncrypt(p, key)
	if err != nil {
		return "", err
	}
	return base64.StdEncoding.EncodeToString(c), nil
}

// Base64AESCBCDecrypt decrypts cipher text encoded by base64 with AES algorithm in CBC mode
func Base64AESCBCDecrypt(c string, key []byte) ([]byte, error) {
	oriCipher, err := base64.StdEncoding.DecodeString(c)
	if err != nil {
		return nil, err
	}
	p, err := AESCBCDecrypt(oriCipher, key)
	if err != nil {
		return nil, err
	}
	return p, nil
}

使用示例如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func main() {
   	p := []byte("plaintext")
	key := []byte("12345678abcdefgh")
	
	ciphertext, _ := Base64AESCBCEncrypt(p, key)
	fmt.Println(ciphertext)

	plaintext, _ := Base64AESCBCDecrypt(ciphertext, key)
	fmt.Println(string(plaintext))
}

运行输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
A67NhD3RBiNaMgG6HTm8LQ==
plaintext

小结

以上代码已放到开源 Go 工具库 go-huge-util,大家如果需要,可直接通过 go mod 方式进行 import 然后使用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import (
	huge "github.com/dablelv/go-huge-util"
)

p := []byte("plaintext")
key := []byte("12345678abcdefgh")

ciphertext, _ := huge.Base64AESCBCEncrypt(p, key)			// A67NhD3RBiNaMgG6HTm8LQ==
plaintext, _ := huge.Base64AESCBCDecrypt(ciphertext, key)	// plaintext

如果想了解 AES 实现原理。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
nuget.exe 还原解决方案 NuGet 包的时候出现错误:调用的目标发生了异常。Error parsing the nested project section in solution file
我这里使用 Visual Studio 2019 能好好编译的一个项目,发现在另一个小伙伴那里却编译不通过,是在 NuGet 还原那里报告了错误:
walterlv
2023/10/22
4520
通过设置 sln 解决方案依赖,确保不引用的两个项目之间有明确的编译顺序
有时在编译解决方案的时候,希望两个项目有明确的编译顺序,而不是自动决定,或者在并行编译的时候同时编译。
walterlv
2023/10/22
5500
通过设置 sln 解决方案依赖,确保不引用的两个项目之间有明确的编译顺序
Visual Studio使用Git忽略不想上传到远程仓库的文件
作为一个.NET开发者而言,有着宇宙最强IDE:Visual Studio加持,让我们的开发效率得到了更好的提升。我们不需要担心环境变量的配置和其他代码管理工具,因为Visual Studio有着众多的拓展工具。废话不多说,直接进入正题。我们日常在使用Visual Studio开发相关的.NET项目时,经常会发现刚拉取下拉的代码什么都没有改动,就是运行了一下就会产生一些需要提交的文件,比如说最常见的bin/Debug, bin/Release,obj/Debug,obj/Release文件。但是我不想把这些文件提交到远程的git代码远程仓库中去,其实这个很简单只需要我们在初次创建项目的时候在项目目录下新增一个忽略文本文件(.gitignore),然后在使用git推送到远程仓库中就好了。
追逐时光者
2025/04/21
990
Visual Studio使用Git忽略不想上传到远程仓库的文件
解决方案文件 sln 中的项目类型 GUID
Visual Studio 可以通过得知项目类型快速地为项目显示相应的图标、对应的功能等等。
walterlv
2023/10/22
3250
Install Jumpserver25
Downloadinghttps://files.pythonhosted.org/packages/36/fa/08e9e6e0e3cbd1d362c3bbee8d01d0aedb2155c4ac112b19ef3cae8eed8d/docutils-0.14-py3-none-any.whl (543kB) 100% |████████████████████████████████| 552kB 618kB/s Collecting ecdsa==0.13 (from -r requirements.txt (line 30)) Downloadinghttps://files.pythonhosted.org/packages/63/f4/73669d51825516ce8c43b816c0a6b64cd6eb71d08b99820c00792cb42222/ecdsa-0.13-py2.py3-none-any.whl (86kB) 100% |████████████████████████████████| 92kB 1.1MB/s Collecting elasticsearch==6.1.1 (from -r requirements.txt (line 31)) Downloadinghttps://files.pythonhosted.org/packages/67/15/80db00582d1d6286c5c8f0e18e444481e0fc2bc1fa2391935f10358c5f2d/elasticsearch-6.1.1-py2.py3-none-any.whl (59kB) 100% |████████████████████████████████| 61kB 2.2MB/s Collecting enum-compat==0.0.2 (from -r requirements.txt (line 32)) Downloadinghttps://files.pythonhosted.org/packages/95/6e/26bdcba28b66126f66cf3e4cd03bcd63f7ae330d29ee68b1f6b623550bfa/enum-compat-0.0.2.tar.gz Collecting ephem==3.7.6.0 (from -r requirements.txt (line 33)) Downloadinghttps://files.pythonhosted.org/packages/c3/2c/9e1a815add6c222a0d4bf7c644e095471a934a39bc90c201f9550a8f7f14/ephem-3.7.6.0.tar.gz (739kB) 100% |████████████████████████████████| 747kB 556kB/s Collecting eventlet==0.22.1 (from -r requirements.txt (line 34)) Downloadinghttps://files.pythonhosted.org/packages/61/1a/d1ff6e4f1dc652dfdda4a674f807c842eaa15f1ed9b76938a3be313bbac9/eventlet-0.22.1-py2.py3-none-any.whl (409kB) 100% |████████████████████████████████| 409kB 558kB/s CollectingForgeryPy==0.1 (from -r requirements.txt (line 35)) Downloadinghttps://files.pythonhosted.org/packages/de/66/8a29d7163b528d2d5c3ccc98e621959723b7eeb010e38c11f1404313e2b7/ForgeryPy-0.1.tar.gz Collecting greenlet==0.4.12 (from -r requirements.txt (line 36)) Downloadinghttps://files.pythonhosted.org/packages/20/ea/e47c2fff6e91b20c05107411fa25fb93e66bd76ecd27f04e2224e7806f41/greenlet-0.4.12-cp36-cp36m-manylinux1_x86_64.whl (42kB) 100% |████████████████████████████████|
franket
2022/07/10
1790
基于Redis实现分布式锁
基于Redis实现分布式锁 一. 基本原理 基于Redis的setnx命令,如果设置成功,则表示当前进程(线程)获取锁成功,否则说明有其他进程已经获取了锁,需进行等待 setnx 的key为需要加锁的资源名称(实例中为方法名),value为业务唯一的id 加锁时需制定锁的过期时间,避免锁未正常释放而导致的死锁问题 加锁时需设置等待超时时间,避免等待时间过长导致系统性能下降 释放锁时,与Redis中的value与当前的业务id进行对比,符合才执行释放操作 二. 代码实现 加锁的核心操作 /** * @Au
张申傲
2020/09/03
3520
(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
发布于 2018-07-25 01:27 更新于 2018-07-26 23:23
walterlv
2018/09/18
1.4K0
(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
使用 dotnet 命令行配合 vscode 完成一个完整 .NET 解决方案的编写和调试
如果你是开发个人项目,那就直接用 Visual Studio Community 版本吧,对个人免费,对小团体免费,不需要这么折腾。
walterlv
2023/10/22
2.3K0
使用 dotnet 命令行配合 vscode 完成一个完整 .NET 解决方案的编写和调试
java.lang.assertionerror_java parseint
Microsoft Visual Studio Solution File, Format Version 12.00
全栈程序员站长
2022/10/04
1.1K0
dotnet Roslyn 通过读取 suo 文件获取解决方案的启动项目
本文来告诉大家一个黑科技,通过 .suo 文件读取 VisualStudio 的启动项目。在 sln 项目里面,都会生成对应的 suo 文件,这个文件是 OLE 格式的文件,文件的格式没有公开,本文的方法适合用在 VisualStudio 2019 上,对于其他版本的 VisualStudio 也许会不适合
林德熙
2021/04/30
7080
理解 C# 项目 csproj 文件格式的本质和编译流程
发布于 2018-05-10 00:13 更新于 2018-08-12 08:11
walterlv
2018/09/18
2.7K0
理解 C# 项目 csproj 文件格式的本质和编译流程
比特币隔离见证交易格式解析(Segregated witness)
如果你还不了解经典交易构成,请看:https://blog.csdn.net/q4878802/article/details/49638457
sickworm
2019/02/27
1.7K0
【Chromium】如何提取Chromium的Base库(下)
本篇文章主要记录如何从Chromium中提取Base库,方便后续的学习和使用,同时抛砖引玉,希望带给各位一些启发和帮助。
lealc
2024/04/17
4290
【Chromium】如何提取Chromium的Base库(下)
Log4Net与Log2Console配合时中文问题的解决
二者搭配,非常好用,但必须要用log4net.Layout.XmlLayoutSchemaLog4j才能有效果:区分不同的级别,把不同的属性列都显示出来… 关于Layout参见:http://www.cnblogs.com/wangchunlan2004/articles/609100.html 排版员 特长 ExceptionLayout 对LoggingEvent中的异常信息message进行排版 PatternLayout 最常用的排版员,通过一堆标识符来决定版式。 如:"%da
用户1075292
2018/01/23
9180
Visual Studio 调试(系列文章)
  Visual Studio 调试程序有助于你观察程序的运行时行为并发现问题。 该调试器可用于所有 Visual Studio 编程语言及其关联的库。 使用调试程序时,可以中断程序的执行以检查代码、检查和编辑变量、查看寄存器、查看从源代码创建的指令,以及查看应用程序占用的内存空间。
张传宁IT讲堂
2019/09/17
8420
Visual Studio 调试(系列文章)
基于 Roslyn 同时为 Visual Studio 插件和 NuGet 包开发 .NET/C# 源代码分析器 Analyzer 和修改器 CodeFixProvider
Roslyn 是 .NET 平台下十分强大的编译器,其提供的 API 也非常丰富好用。本文将基于 Roslyn 开发一个 C# 代码分析器,你不止可以将分析器作为 Visual Studio 代码分析和重构插件发布,还可以作为 NuGet 包发布。不管哪一种,都可以让我们编写的 C# 代码分析器工作起来并真正起到代码建议和重构的作用。
walterlv
2023/10/23
8680
基于 Roslyn 同时为 Visual Studio 插件和 NuGet 包开发 .NET/C# 源代码分析器 Analyzer 和修改器 CodeFixProvider
制作通过 NuGet 分发的源代码包时,如果目标项目是 WPF 则会出现一些问题(探索篇,含解决方案)
在使用 NuGet 包来分发源代码时,如果目标项目是 WPF 项目,那么会有一大堆的问题。
walterlv
2023/10/22
5380
制作通过 NuGet 分发的源代码包时,如果目标项目是 WPF 则会出现一些问题(探索篇,含解决方案)
C# 如何部分加载“超大”解决方案中的部分项目
在有的特有的项目环境下,团队会将所有的项目使用同一个解决方案进行管理。这种方式方面了管理,但是却会导致解决方案变得非常庞大,导致加载时间过长。那么,如何部分加载解决方案中的部分项目呢?就让我们来借用微软退出的 slngen 工具来体验一下部分加载解决方案中的部分项目吧。
newbe36524
2023/08/23
3250
WPF:无法对元素“XXX”设置 Name 特性值“YYY”。“XXX”在元素“ZZZ”的范围内,在另一范围内定义它时,已注册了名称。
2020-04-03 06:44
walterlv
2020/04/08
3.3K0
如何修改visual-studio的sln文件和project工程名
Visual Studio.NET采用两种文件类型(.sln和.suo)来存储特定于解决方案的设置,它们总称为解决方案文件。为解决方案资源管理器提供显示管理文件的图形接口所需的信息,从而在每次继续开发任务时,不会因开发环境而分散精力;
全栈程序员站长
2022/08/23
2.1K0
如何修改visual-studio的sln文件和project工程名
推荐阅读
nuget.exe 还原解决方案 NuGet 包的时候出现错误:调用的目标发生了异常。Error parsing the nested project section in solution file
4520
通过设置 sln 解决方案依赖,确保不引用的两个项目之间有明确的编译顺序
5500
Visual Studio使用Git忽略不想上传到远程仓库的文件
990
解决方案文件 sln 中的项目类型 GUID
3250
Install Jumpserver25
1790
基于Redis实现分布式锁
3520
(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
1.4K0
使用 dotnet 命令行配合 vscode 完成一个完整 .NET 解决方案的编写和调试
2.3K0
java.lang.assertionerror_java parseint
1.1K0
dotnet Roslyn 通过读取 suo 文件获取解决方案的启动项目
7080
理解 C# 项目 csproj 文件格式的本质和编译流程
2.7K0
比特币隔离见证交易格式解析(Segregated witness)
1.7K0
【Chromium】如何提取Chromium的Base库(下)
4290
Log4Net与Log2Console配合时中文问题的解决
9180
Visual Studio 调试(系列文章)
8420
基于 Roslyn 同时为 Visual Studio 插件和 NuGet 包开发 .NET/C# 源代码分析器 Analyzer 和修改器 CodeFixProvider
8680
制作通过 NuGet 分发的源代码包时,如果目标项目是 WPF 则会出现一些问题(探索篇,含解决方案)
5380
C# 如何部分加载“超大”解决方案中的部分项目
3250
WPF:无法对元素“XXX”设置 Name 特性值“YYY”。“XXX”在元素“ZZZ”的范围内,在另一范围内定义它时,已注册了名称。
3.3K0
如何修改visual-studio的sln文件和project工程名
2.1K0
相关推荐
nuget.exe 还原解决方案 NuGet 包的时候出现错误:调用的目标发生了异常。Error parsing the nested project section in solution file
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验