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中实现给gif、png、jpeg图片添加文字水印
Apr 26 Golang
goland 清除所有的默认设置操作
Apr 28 Golang
golang 实现对Map进行键值自定义排序
Apr 28 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
Golang 如何实现函数的任意类型传参
Apr 29 Golang
Golang 语言控制并发 Goroutine的方法
Jun 30 Golang
浅谈GO中的Channel以及死锁的造成
Mar 18 Golang
如何解决goland,idea全局搜索快捷键失效问题
Apr 03 Golang
victoriaMetrics库布隆过滤器初始化及使用详解
Apr 05 Golang
golang使用map实现去除重复数组
Apr 14 Golang
Go gRPC进阶教程gRPC转换HTTP
Jun 16 Golang
GoFrame基于性能测试得知grpool使用场景
Jun 21 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/03/25 PHP
推荐几款用 Sublime Text 开发 Laravel 所用到的插件
2014/10/30 PHP
自己写的php中文截取函数mb_strlen和mb_substr
2015/02/09 PHP
自己写了一个展开和收起的多更能型的js效果
2013/03/05 Javascript
javascript搜索框点击文字消失失焦时文本出现
2014/09/18 Javascript
利用JQuery直接调用asp.net后台的简单方法
2016/10/27 Javascript
js判断出两个字符串最大子串的函数实现方法
2016/11/01 Javascript
BootStrap实现文件上传并带有进度条效果
2017/09/11 Javascript
Vue-router 类似Vuex实现组件化开发的示例
2017/09/15 Javascript
React Native 真机断点调试+跨域资源加载出错问题的解决方法
2018/01/18 Javascript
node.js到底要不要加分号浅析
2018/07/11 Javascript
mpvue小程序循环动画开启暂停的实现方法
2019/05/15 Javascript
express启用https使用小记
2019/05/21 Javascript
原生JavaScript实现的无缝滚动功能详解
2020/01/17 Javascript
Vue 3.0 全家桶抢先体验
2020/04/28 Javascript
Vue.js中使用Vuex实现组件数据共享案例
2020/07/31 Javascript
react-intl实现React国际化多语言的方法
2020/09/27 Javascript
原生js实现自定义滚动条
2021/01/20 Javascript
[04:39]显微镜下的DOTA2第十三期—Pis卡尔个人秀
2014/04/04 DOTA
Python绘制正余弦函数图像的方法
2018/08/28 Python
关于PyCharm安装后修改路径名称使其可重新打开的问题
2020/10/20 Python
Selenium获取登录Cookies并添加Cookies自动登录的方法
2020/12/04 Python
如何用 Python 处理不平衡数据集
2021/01/04 Python
Html5与App的通讯方式详解
2019/10/24 HTML / CSS
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
大学生简单自荐信
2013/11/10 职场文书
上级检查欢迎词
2014/01/18 职场文书
小学教师师德感言
2014/02/10 职场文书
技校毕业生自荐信范文
2014/03/07 职场文书
学生检讨书怎么写?
2014/10/10 职场文书
2015年考研复习计划
2015/01/19 职场文书
房产公证书样本
2015/01/23 职场文书
前台接待员岗位职责
2015/04/15 职场文书
给校长的建议书范文
2015/09/14 职场文书
Python 解决空列表.append() 输出为None的问题
2021/05/23 Python
Nginx配置之禁止指定IP访问
2022/05/02 Servers