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 30 Golang
解决golang post文件时Content-Type出现的问题
May 02 Golang
golang switch语句的灵活写法介绍
May 06 Golang
解决Goland 同一个package中函数互相调用的问题
May 06 Golang
go语言基础 seek光标位置os包的使用
May 09 Golang
go web 预防跨站脚本的实现方式
Jun 11 Golang
Go 语言中 20 个占位符的整理
Oct 16 Golang
Go语言的协程上下文的几个方法和用法
Apr 11 Golang
Golang流模式之grpc的四种数据流
Apr 13 Golang
Go语言grpc和protobuf
Apr 13 Golang
Golang 实现WebSockets
Apr 24 Golang
Go web入门Go pongo2模板引擎
May 20 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
为什么夜间收到的中波电台比白天多
2021/03/01 无线电
php构造函数的继承方法
2015/02/09 PHP
PHP实现全角字符转为半角方法汇总
2015/07/09 PHP
动态添加js事件实现代码
2009/03/12 Javascript
JavaScript之IE的fireEvent方法详细解析
2013/11/20 Javascript
将form表单中的元素转换成对象的方法适用表单提交
2014/05/02 Javascript
javascript trim函数在IE下不能用的解决方法
2014/09/12 Javascript
基于javascript实现的搜索时自动提示功能
2014/12/26 Javascript
windows下安装nodejs及框架express
2015/08/07 NodeJs
jquery仿百度百科底部浮动导航特效
2015/08/08 Javascript
AngularJS 与百度地图的结合实例
2016/10/20 Javascript
Web开发中客户端的跳转与服务器端的跳转的区别
2017/03/05 Javascript
纯JS实现简单的日历
2017/06/26 Javascript
利用js编写网页进度条效果
2017/10/08 Javascript
Vue2.5通过json文件读取数据的方法
2018/02/27 Javascript
electron制作仿制qq聊天界面的示例代码
2018/11/26 Javascript
13 个npm 快速开发技巧(推荐)
2019/07/04 Javascript
解决LayUI数据表格复选框不居中显示的问题
2019/09/25 Javascript
在vue中使用eslint,配合vscode的操作
2020/11/09 Javascript
关于小程序优化的一些建议(小结)
2020/12/10 Javascript
jQuery+ajax实现文件上传功能
2020/12/22 jQuery
Python multiprocessing模块中的Pipe管道使用实例
2015/04/11 Python
Python简单进程锁代码实例
2015/04/27 Python
python 文件操作api(文件操作函数)
2016/08/28 Python
Python字符串拼接的几种方法整理
2017/08/02 Python
python数据抓取3种方法总结
2021/02/07 Python
解决PDF 转图片时丢文字的一种可能方式
2021/03/04 Python
基于CSS3的animation属性实现微信拍一拍动画效果
2020/06/22 HTML / CSS
新西兰杂志订阅:isubscribe
2019/08/26 全球购物
精伦电子Java笔试题
2013/01/16 面试题
杭州SQL浙江浙大网新恩普软件有限公司
2013/07/27 面试题
运动会通讯稿200字
2014/02/16 职场文书
高中军训感言1000字
2014/03/01 职场文书
大学生实习证明范本
2014/09/19 职场文书
2019学子的答谢词范本!
2019/07/05 职场文书
Python pandas之求和运算和非空值个数统计
2021/08/07 Python