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缓冲channel和非缓冲channel的区别说明
Apr 25 Golang
golang http使用踩过的坑与填坑指南
Apr 27 Golang
golang在GRPC中设置client的超时时间
Apr 27 Golang
Go 实现英尺和米的简单单位换算方式
Apr 29 Golang
goland 设置project gopath的操作
May 06 Golang
Go 语言结构实例分析
Jul 04 Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 Golang
深入理解go slice结构
Sep 15 Golang
Go 语言中 20 个占位符的整理
Oct 16 Golang
Golang原生rpc(rpc服务端源码解读)
Apr 07 Golang
Golang数据类型和相互转换
Apr 12 Golang
Golang获取List列表元素的四种方式
Apr 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
MySQL数据库转移,access,sql server 转 MySQL 的图文教程
2007/09/02 PHP
PHP实现数组递归转义的方法
2014/08/28 PHP
用PHP代码在网页上生成图片
2015/07/01 PHP
PHP加密解密函数详解
2015/10/28 PHP
PHP生成随机数的方法总结
2018/03/01 PHP
使用swoole 定时器变更超时未支付订单状态的解决方案
2019/07/24 PHP
Jquery 弹出层插件实现代码
2009/10/24 Javascript
js/jquery解析json和数组格式的方法详解
2014/01/09 Javascript
JavaScript基础教程之alert弹出提示框实例
2014/10/16 Javascript
IE8下jQuery改变png图片透明度时出现的黑边
2015/08/30 Javascript
JS实现浏览器状态栏显示时间的方法
2015/10/27 Javascript
jQuery 中ajax异步调用的四种方式
2016/06/28 Javascript
jQuery 局部div刷新和全局刷新方法总结
2016/10/05 Javascript
微信js-sdk界面操作接口用法示例
2016/10/12 Javascript
JQuery和html+css实现带小圆点和左右按钮的轮播图实例
2017/07/22 jQuery
基于jQuery实现的单行公告活动轮播效果
2017/08/23 jQuery
vue路由切换之淡入淡出的简单实现
2019/10/31 Javascript
element-ui封装一个Table模板组件的示例
2021/01/04 Javascript
jenkins自动构建发布vue项目的方法步骤
2021/01/04 Vue.js
聊聊vue 中的v-on参数问题
2021/01/29 Vue.js
Python实现的检测网站挂马程序
2014/11/30 Python
python使用Thread的setDaemon启动后台线程教程
2020/04/25 Python
pycharm2020.2 配置使用的方法详解
2020/09/16 Python
详解Python中list[::-1]的几种用法
2020/11/16 Python
韩国美国时尚服装和美容在线全球市场:KOODING
2018/11/07 全球购物
瑞典的玛丽小姐:Miss Mary of Sweden
2019/02/13 全球购物
C#如何允许一个类被继承但是避免这个类的方法被重载?
2015/02/24 面试题
2014年幼儿园个人工作总结
2014/11/10 职场文书
2014年工程部工作总结
2014/11/25 职场文书
模范教师事迹材料
2014/12/16 职场文书
教师听课评语大全
2014/12/31 职场文书
妈妈再爱我一次观后感
2015/06/08 职场文书
祝寿主持词
2015/07/02 职场文书
深度好文:50条没人告诉你的人生经验,句句精辟
2019/08/22 职场文书
Python爬虫进阶之Beautiful Soup库详解
2021/04/29 Python
使用springMVC所需要的pom配置
2021/09/15 Java/Android