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 相关文章推荐
解决Golang中ResponseWriter的一个坑
Apr 27 Golang
golang 实现对Map进行键值自定义排序
Apr 28 Golang
使用Golang的channel交叉打印两个数组的操作
Apr 29 Golang
golang 实现Location跳转方式
May 02 Golang
Goland使用Go Modules创建/管理项目的操作
May 06 Golang
Golang Gob编码(gob包的使用详解)
May 07 Golang
Go语言并发编程 sync.Once
Oct 16 Golang
Go语言读取txt文档的操作方法
Jan 22 Golang
浅谈GO中的Channel以及死锁的造成
Mar 18 Golang
golang操作redis的客户端包有多个比如redigo、go-redis
Apr 14 Golang
Go web入门Go pongo2模板引擎
May 20 Golang
Go语言怎么使用变长参数函数
Jul 15 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下连接mssql2005的代码
2011/01/17 PHP
thinkphp路由规则使用示例详解和伪静态功能实现(apache重写)
2014/02/24 PHP
PhpDocumentor 2安装以及生成API文档的方法
2014/05/21 PHP
PHP使用静态方法的几个注意事项
2014/09/16 PHP
PHP也能干大事 随机函数
2015/04/14 PHP
PHP判断来访是搜索引擎蜘蛛还是普通用户的代码小结
2015/09/14 PHP
php中请求url的五种方法总结
2017/07/13 PHP
PHP封装的简单连接MongoDB类示例
2019/02/13 PHP
发布一个高效的JavaScript分析、压缩工具 JavaScript Analyser
2007/11/30 Javascript
js实时监听文本框状态的方法
2011/04/26 Javascript
jQuery修改CSS伪元素属性的方法
2014/07/30 Javascript
动态加载jQuery的方法
2015/06/16 Javascript
分享两段简单的JS代码防止SQL注入
2016/04/12 Javascript
JS通过ajax + 多列布局 + 自动加载实现瀑布流效果
2019/05/30 Javascript
js中Function引用类型常见有用的方法和属性详解
2019/12/11 Javascript
vue-openlayers实现地图坐标弹框效果
2020/09/24 Javascript
JavaScript 中的执行上下文和执行栈实例讲解
2021/02/25 Javascript
[51:15]2014 DOTA2国际邀请赛中国区预选赛 Orenda VS LGD-GAMING
2014/05/22 DOTA
[06:44]2014DOTA2国际邀请赛-钥匙体育馆开战 开幕式振奋人心
2014/07/19 DOTA
[01:57]DOTA2上海特锦赛小组赛解说单车采访花絮
2016/02/27 DOTA
Python高级用法总结
2018/05/26 Python
win8.1安装Python 2.7版环境图文详解
2019/07/01 Python
Python如何telnet到网络设备
2021/02/18 Python
对CSS3选择器的研究(详解)
2016/09/16 HTML / CSS
Helly Hansen工作服美国官方网上商店:为最恶劣的环境
2019/09/04 全球购物
UNIX文件系统常用命令
2012/05/25 面试题
自我鉴定怎么写
2013/12/05 职场文书
酒吧总经理岗位职责
2013/12/10 职场文书
料理师求职信
2014/01/30 职场文书
洗车工岗位职责
2014/03/15 职场文书
2014国庆节商场促销活动策划方案
2014/09/16 职场文书
专题组织生活会思想汇报
2014/10/01 职场文书
办公室班子四风问题对照检查材料
2014/10/04 职场文书
销售助理岗位职责
2015/02/11 职场文书
Python爬虫基础之爬虫的分类知识总结
2021/05/13 Python
python库sklearn常用操作
2021/08/23 Python