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 interface{}==nil 的几种坑及原理分析
Apr 24 Golang
go原生库的中bytes.Buffer用法
Apr 25 Golang
golang如何去除多余空白字符(含制表符)
Apr 25 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
对Golang中的FORM相关字段理解
May 02 Golang
Golang标准库syscall详解(什么是系统调用)
May 25 Golang
Go语言基础切片的创建及初始化示例详解
Nov 17 Golang
Go语言读取txt文档的操作方法
Jan 22 Golang
Golang 结构体数据集合
Apr 22 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 Golang
go goth封装第三方认证库示例详解
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超级全局变量数组小结
2012/10/04 PHP
PHP框架Swoole定时器Timer特性分析
2014/08/19 PHP
php+js实现的无刷新下载文件功能示例
2019/08/23 PHP
JavaScript类和继承 prototype属性
2010/09/03 Javascript
Jquery为单选框checkbox绑定单击click事件
2012/12/18 Javascript
javascript中处理时间戳为日期格式的方法
2014/01/02 Javascript
Javascript学习笔记之函数篇(五) : 构造函数
2014/11/23 Javascript
js实现按钮控制图片360度翻转特效的方法
2015/02/17 Javascript
14 个折磨人的 JavaScript 面试题
2016/08/08 Javascript
Vue.js每天必学之过渡与动画
2016/09/06 Javascript
JavaScript中的await/async的作用和用法
2016/10/31 Javascript
js中获取键盘按下键值event.keyCode、event.charCode和event.which的兼容性详解
2017/03/15 Javascript
20行js代码实现的贪吃蛇小游戏
2017/06/20 Javascript
JavaScript中常见的八个陷阱总结
2017/06/28 Javascript
vue-cli项目无法用本机IP访问的解决方法
2018/09/20 Javascript
对vue中v-if的常见使用方法详解
2018/09/28 Javascript
node中IO以及定时器优先级详解
2019/05/10 Javascript
JS数组方法concat()用法实例分析
2020/01/18 Javascript
Vue快速实现通用表单验证的方法
2020/02/24 Javascript
Python语言的变量认识及操作方法
2018/02/11 Python
解决Python的str强转int时遇到的问题
2018/04/09 Python
python利用appium实现手机APP自动化的示例
2021/01/26 Python
html5播放视频且动态截图实现步骤与代码(支持safari其他未测试)
2013/01/06 HTML / CSS
html5 video全屏播放/自动播放的实现示例
2020/08/06 HTML / CSS
阿玛尼美妆加拿大官方商城:Giorgio Armani Beauty加拿大
2017/10/24 全球购物
澳大利亚儿童精品仓库:Goo & Co.
2019/06/20 全球购物
ORACLE十问
2015/04/20 面试题
公司员工的自我评价范例
2013/11/01 职场文书
竞聘书格式及范文
2014/03/31 职场文书
2014年度安全生产目标管理责任书
2014/07/25 职场文书
逃课检讨书怎么写
2015/01/01 职场文书
检讨书怎么写
2015/01/23 职场文书
司机岗位职责
2015/02/04 职场文书
2016年记者节感言
2015/12/08 职场文书
ORACLE查看当前账号的相关信息
2021/06/18 Oracle
Python中使用tkFileDialog实现文件选择、保存和路径选择
2022/05/20 Python