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 嵌套 interface 的赋值问题
Apr 29 Golang
浅谈golang package中init方法的多处定义及运行顺序问题
May 06 Golang
go 实现简易端口扫描的示例
May 22 Golang
Golang标准库syscall详解(什么是系统调用)
May 25 Golang
Golang 语言控制并发 Goroutine的方法
Jun 30 Golang
Golang中channel的原理解读(推荐)
Oct 16 Golang
Go语言基础map用法及示例详解
Nov 17 Golang
深入理解go缓存库freecache的使用
Feb 15 Golang
golang实现浏览器导出excel文件功能
Mar 25 Golang
Golang数据类型和相互转换
Apr 12 Golang
GO语言异常处理分析 err接口及defer延迟
Apr 14 Golang
Golang ort 中的sortInts 方法
Apr 24 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入门源程序
2006/10/09 PHP
PHP 危险函数全解析
2009/09/09 PHP
phpmyadmin导入(import)文件限制的解决办法
2009/12/11 PHP
php输出表格的实现代码(修正版)
2010/12/29 PHP
yii框架通过控制台命令创建定时任务示例
2014/04/30 PHP
php实现猴子选大王问题算法实例
2015/04/20 PHP
Linux下快速搭建php开发环境
2017/03/13 PHP
php生成微信红包数组的方法
2019/09/05 PHP
判断多个元素(RADIO,CHECKBOX等)是否被选择的原理说明
2009/02/18 Javascript
基于jQuery的公告无限循环滚动实现代码
2012/05/11 Javascript
原生JS实现LOADING效果
2015/03/16 Javascript
javascript消除window.close()的提示窗口
2015/05/20 Javascript
鼠标经过子元素触发mouseout,mouseover事件的解决方案
2015/07/26 Javascript
jQuery遍历json的方法分析
2016/04/16 Javascript
babel基本使用详解
2017/02/17 Javascript
详解webpack+gulp实现自动构建部署
2017/06/29 Javascript
js + css实现标签内容切换功能(实例讲解)
2017/10/09 Javascript
详解nuxt sass全局变量(公共scss解决方案)
2018/06/27 Javascript
vue+webpack模拟后台数据的示例代码
2018/07/26 Javascript
nodejs初始化init的示例代码
2018/10/10 NodeJs
JavaScript实现身份证验证代码实例
2019/08/26 Javascript
layui table动态表头 改变表格头部 重新加载表格的方法
2019/09/21 Javascript
ant-design-vue 时间选择器赋值默认时间的操作
2020/10/27 Javascript
解决vue初始化项目一直停在downloading template的问题
2020/11/09 Javascript
python删除过期log文件操作实例解析
2018/01/31 Python
在python中pandas读文件,有中文字符的方法
2018/12/12 Python
python+selenium 定位到元素,无法点击的解决方法
2019/01/30 Python
Python中的正则表达式与JSON数据交换格式
2019/07/03 Python
python检查目录文件权限并修改目录文件权限的操作
2020/03/11 Python
表单button的outline在firefox浏览器下的问题
2012/12/24 HTML / CSS
技术副厂长岗位职责
2013/12/26 职场文书
审计局2014法制宣传日活动总结
2014/11/01 职场文书
异地恋情人节寄语
2015/02/28 职场文书
纪念建国70周年演讲稿
2019/07/19 职场文书
2019年汽车租赁合同范本!
2019/08/12 职场文书
导游词之云南省玉龙雪山
2019/12/19 职场文书