Golang实现AES对称加密的过程详解

AES是一个对称密码,旨在取代DES成为广泛使用的标准,本文给大家分享Golang实现AES对称加密的过程,本文附有Golang实现AES加密ECB模式的源码,感兴趣的朋友跟随小编一起学习下吧

Posted in Golang onMay 20, 2021

AES加密

AES对称加密简介
AES是一个对称密码,旨在取代DES成为广泛使用的标准。是美国联邦政府采用的一种区块加密标准。

AES对称加密过程
加密解密算法的输入是一个128位分组。这些分组被描述成4×4的字节方阵,这个分组被复制到数组中,并在加密和解密的每一阶段都被修改。在字节方阵中,每一格都是一个字,包含了4字节。在矩阵中字是按列排序的。
加密由N轮构成,轮数依赖于密钥长度:16字节密钥对应10轮,24字节密钥对应12轮,32字节对应14轮。

AES加密模式

1.电码本模式(Electronic Codebook Book (ECB)

ECB模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。

2.密码分组链接模式(Cipher Block Chaining (CBC))

这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。

3.密码反馈模式(Cipher FeedBack (CFB))
隐藏了明文模式,分组密码转化为流模式,可以及时加密传送小于分组的数据

4.OFB(Output FeedBack,输出反馈)模式
隐藏了明文模式;,分组密码转化为流模式,可以及时加密传送小于分组的数据

AES填充方式
AES支持支持几种填充:NoPadding,PKCS5Padding,ISO10126Padding,PaddingMode.Zeros,PaddingMode.PKCS7。对于AES来说PKCS5Padding和PKCS7Padding是完全一样的,不同在于PKCS5限定了块大小为8bytes而PKCS7没有限定。因此对于AES来说两者完全相同

Golang实现AES加密解密

下面附上Golang实现AES加密ECB模式的源码:

package main
import (
    "bytes"
    "crypto/aes"
    "fmt"
    "testing"
)
 
//ECB模式解密
func ECBDecrypt(crypted, key []byte) ([]byte, error) {
    if !validKey(key) {
        return nil, fmt.Errorf("秘钥长度错误,当前传入长度为 %d",len(key))
    }
    if len(crypted) < 1 {
        return nil, fmt.Errorf("源数据长度不能为0")
    }
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    if len(crypted)%block.BlockSize() != 0 {
        return nil, fmt.Errorf("源数据长度必须是 %d 的整数倍,当前长度为:%d",block.BlockSize(), len(crypted))
    }
    var dst []byte
    tmpData := make([]byte, block.BlockSize())
 
    for index := 0; index < len(crypted); index += block.BlockSize() {
        block.Decrypt(tmpData, crypted[index:index+block.BlockSize()])
        dst = append(dst, tmpData...)
    }
    dst, err = PKCS5UnPadding(dst)
    if err != nil {
        return nil, err
    }
    return dst, nil
}
 
//ECB模式加密
func ECBEncrypt(src, key []byte) ([]byte, error) {
    if !validKey(key) {
        return nil, fmt.Errorf("秘钥长度错误, 当前传入长度为 %d",len(key))
    }
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, err
    }
    if len(src) < 1 {
        return nil, fmt.Errorf("源数据长度不能为0")
    }
    src = PKCS5Padding(src, block.BlockSize())
    if len(src)%block.BlockSize() != 0 {
        return nil, fmt.Errorf("源数据长度必须是 %d 的整数倍,当前长度为:%d",block.BlockSize(), len(src))
    }
    var dst []byte
    tmpData := make([]byte, block.BlockSize())
    for index := 0; index < len(src); index += block.BlockSize() {
        block.Encrypt(tmpData, src[index:index+block.BlockSize()])
        dst = append(dst, tmpData...)
    }
    return dst, nil
}
 
// PKCS5填充
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
    padding := blockSize - len(ciphertext)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(ciphertext, padtext...)
}
 
// 去除PKCS5填充
func PKCS5UnPadding(origData []byte) ([]byte, error) {
    length := len(origData)
    unpadding := int(origData[length-1])
 
    if length < unpadding {
        return nil, fmt.Errorf("invalid unpadding length")
    }
    return origData[:(length - unpadding)], nil
}
 
// 秘钥长度验证
func validKey(key []byte) bool {
    k := len(key)
    switch k {
    default:
        return false
    case 16, 24, 32:
        return true
    }
}
 
func TestAes(t *testing.T){
    srcData := "hello world !"
    key := []byte("abcdabcdabcdabcdabcdabcdabcdabcd")
    //测试加密
    encData ,err := ECBEncrypt([]byte(srcData),(key))
    if err != nil {
        t.Errorf(err.Error())
        return
    }
 
    //测试解密
    decData ,err := ECBDecrypt(encData,key)
    if err != nil {
        t.Errorf(err.Error())
        return
    }
    t.Log(string(decData))
}

以上就是Golang实现AES对称加密的过程详解的详细内容

Golang 相关文章推荐
Go语言操作数据库及其常规操作的示例代码
Apr 21 Golang
Go语言使用select{}阻塞main函数介绍
Apr 25 Golang
Go缓冲channel和非缓冲channel的区别说明
Apr 25 Golang
用golang如何替换某个文件中的字符串
Apr 25 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
golang协程池模拟实现群发邮件功能
May 02 Golang
golang中的struct操作
Nov 11 Golang
golang使用map实现去除重复数组
Apr 14 Golang
Golang 切片(Slice)实现增删改查
Apr 22 Golang
Go语言入门exec的基本使用
May 20 Golang
详解Go语言中Get/Post请求测试
Jun 01 Golang
Go中使用gjson来操作JSON数据的实现
Aug 14 Golang
go语言基础 seek光标位置os包的使用
May 09 #Golang
Golang 实现获取当前函数名称和文件行号等操作
May 08 #Golang
Golang 获取文件md5校验的方法以及效率对比
May 08 #Golang
GoLang中生成UUID唯一标识的实现
May 08 #Golang
聊聊golang中多个defer的执行顺序
May 08 #Golang
Golang全局变量加锁的问题解决
golang 实现并发求和
May 08 #Golang
You might like
PHP实现更改hosts文件的方法示例
2017/08/08 PHP
php单元测试phpunit入门实例教程
2017/11/17 PHP
js中的escape及unescape函数的php实现代码
2007/09/04 Javascript
jQuery的链式调用浅析
2010/12/03 Javascript
js限制文本框只能输入数字(正则表达式)
2012/07/15 Javascript
js简单抽奖代码
2015/01/16 Javascript
深入探寻seajs的模块化与加载方式
2015/04/14 Javascript
JavaScript中的slice()方法使用详解
2015/06/06 Javascript
JS延时提示框实现方法详解
2015/11/26 Javascript
JS字符串的切分用法实例
2016/02/22 Javascript
原生JS实现图片轮播切换效果
2016/12/15 Javascript
angular分页指令操作
2017/01/09 Javascript
详解vue 实例方法和数据
2017/10/23 Javascript
vue单页缓存方案分析及实现
2018/09/25 Javascript
微信小程序实现banner图轮播效果
2020/06/28 Javascript
ES6 Generator函数的应用实例分析
2019/06/26 Javascript
js抽奖转盘实现方法分析
2020/05/16 Javascript
Python切换pip安装源的方法详解
2016/11/18 Python
Python使用matplotlib绘制多个图形单独显示的方法示例
2018/03/14 Python
python 爬虫 批量获取代理ip的实例代码
2018/05/22 Python
Python 运行 shell 获取输出结果的实例
2019/01/07 Python
python随机生成大小写字母数字混合密码(仅20行代码)
2020/02/01 Python
手把手教你进行Python虚拟环境配置教程
2020/02/03 Python
解决Pycharm中恢复被exclude的项目问题(pycharm source root)
2020/02/14 Python
Python批量启动多线程代码实例
2020/02/18 Python
浅谈django 模型类使用save()方法的好处与注意事项
2020/03/28 Python
Python多线程实现支付模拟请求过程解析
2020/04/21 Python
HTML5所有标签汇总及标签意义解释
2015/03/12 HTML / CSS
Pure Collection美国官网:来自英国羊绒专家的奢华羊绒
2017/11/19 全球购物
一篇.NET面试题
2014/09/29 面试题
LINUX下线程,GDI类的解释
2016/12/14 面试题
自荐信格式简述
2014/01/25 职场文书
银行求职自荐信
2014/06/30 职场文书
毕业论文致谢范文
2015/05/14 职场文书
2015国庆节66周年标语
2015/07/30 职场文书
Python数据可视化之基于pyecharts实现的地理图表的绘制
2021/06/10 Python