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 Gin实现文件上传下载的示例代码
Apr 02 Golang
对Golang中的FORM相关字段理解
May 02 Golang
解决golang post文件时Content-Type出现的问题
May 02 Golang
浅谈golang 中time.After释放的问题
May 05 Golang
完美解决golang go get私有仓库的问题
May 05 Golang
Golang标准库syscall详解(什么是系统调用)
May 25 Golang
如何解决goland,idea全局搜索快捷键失效问题
Apr 03 Golang
golang的文件创建及读写操作
Apr 14 Golang
Golang 结构体数据集合
Apr 22 Golang
Golang并发工具Singleflight
May 06 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创建多级目录代码
2008/06/05 PHP
PHP实现根据设备类型自动跳转相应页面的方法
2014/07/24 PHP
php实现paypal 授权登录
2015/05/28 PHP
php文件操作之小型留言本实例
2015/06/20 PHP
详解PHP使用日期时间处理器Carbon人性化显示时间
2017/08/10 PHP
PHP实现基于栈的后缀表达式求值功能
2017/11/10 PHP
php 使用ActiveMQ发送消息,与处理消息操作示例
2020/02/23 PHP
Nigma vs Liquid BO3 第二场2.14
2021/03/10 DOTA
javascript之dhDataGrid Ver2.0.0代码
2007/07/01 Javascript
escape、encodeURI 和 encodeURIComponent 的区别
2009/03/02 Javascript
JQuery 小练习(实例代码)
2009/08/07 Javascript
基于jquery实现的文字向上跑动类似跑马灯的效果
2014/06/17 Javascript
Javascript遍历Html Table示例(包括内容和属性值)
2014/07/08 Javascript
JavaScript实现关键字高亮功能
2014/11/12 Javascript
javascript数据类型示例分享
2015/01/19 Javascript
JavaScript实现点击文字切换登录窗口的方法
2015/05/11 Javascript
JS日期加减,日期运算代码
2015/11/05 Javascript
BootStrap的JS插件之轮播效果案例详解
2016/05/16 Javascript
BootStrap Table 分页后重新搜索问题的解决办法
2016/08/08 Javascript
使用ajaxfileupload.js实现上传文件功能
2016/08/13 Javascript
jQuery基于正则表达式的表单验证功能示例
2017/01/21 Javascript
JS ES6多行字符串与连接字符串的表示方法
2017/04/26 Javascript
socket.io学习教程之深入学习篇(三)
2017/04/29 Javascript
微信小程序日历组件calendar详解及实例
2017/06/08 Javascript
vue slot与传参实例代码讲解
2019/04/28 Javascript
解决layui追加或者动态修改的表单元素“没效果”的问题
2019/09/18 Javascript
python使用beautifulsoup从爱奇艺网抓取视频播放
2014/01/23 Python
Python中使用摄像头实现简单的延时摄影技术
2015/03/27 Python
Tensorflow实现卷积神经网络用于人脸关键点识别
2018/03/05 Python
PyQt5根据控件Id获取控件对象的方法
2019/06/25 Python
如何让python的运行速度得到提升
2020/07/08 Python
基于Python-Pycharm实现的猴子摘桃小游戏(源代码)
2021/02/20 Python
internal修饰符起什么作用
2013/12/16 面试题
基层党员群众路线教育实践活动个人对照检查材料思想汇报
2014/10/05 职场文书
python小程序之飘落的银杏
2021/04/17 Python
Python绘画好看的星空图
2022/03/17 Python