Golang实现AES对称加密的过程详解

 更新时间:2021年05月20日 14:48:08   作者:写Golang的小张  
AES是一个对称密码,旨在取代DES成为广泛使用的标准,本文给大家分享Golang实现AES对称加密的过程,本文附有Golang实现AES加密ECB模式的源码,感兴趣的朋友跟随小编一起学习下吧

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对称加密的过程详解的详细内容,更多关于go AES对称加密的资料请关注脚本之家其它相关文章!

相关文章

  • Go语言数据结构之二叉树必会知识点总结

    Go语言数据结构之二叉树必会知识点总结

    如果你是一个开发人员,或多或少对树型结构都有一定的认识。二叉树作为树的一种,是一种重要的数据结构,也是面试官经常考的东西。本文为大家总结了一些二叉树必会知识点,需要的可以参考一下
    2022-08-08
  • Go语言正则表达式的使用详解

    Go语言正则表达式的使用详解

    正则表达式是一种进行模式匹配和文本操纵的功能强大的工具。这篇文章主要介绍了Go正则表达式使用,本文给大家介绍的非常详细,对大家的工作或学习具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • goland服务热重启的配置文件

    goland服务热重启的配置文件

    这篇文章主要介绍了goland服务热重启的配置文件,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Go语言接口定义与用法示例

    Go语言接口定义与用法示例

    这篇文章主要介绍了Go语言接口定义与用法,较为详细的分析了Go语言中接口的概念、定义、用法,需要的朋友可以参考下
    2016-07-07
  • Golang如何使用go.mod配置加载本地模块

    Golang如何使用go.mod配置加载本地模块

    这篇文章主要介绍了Golang如何使用go.mod配置加载本地模块问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Go实现比较时间大小

    Go实现比较时间大小

    这篇文章主要介绍了Go实现比较时间大小的方法和示例,非常的简单实用,有需要的小伙伴可以参考下。
    2015-04-04
  • 详解Golang编程中的常量与变量

    详解Golang编程中的常量与变量

    这篇文章主要介绍了详解Golang编程中的常量与变量,是Go语言入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • 详解Go语言如何进行Http调用

    详解Go语言如何进行Http调用

    无论是微服务还是单体架构等,服务间都有相互通信的时候,而最直接的通信方法就是 HTTP 调用,本文将会介绍在 Go 语言里,如何进行 HTTP 调用,需要的可以参考一下
    2022-12-12
  • Golang实现延迟调用的项目实践

    Golang实现延迟调用的项目实践

    本文主要介绍了Golang实现延迟调用的项目实践,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-02-02
  • go内置函数copy()的具体使用

    go内置函数copy()的具体使用

    当我们在Go语言中需要将一个切片的内容复制到另一个切片时,可以使用内置的copy()函数,本文就介绍了go内置函数copy()的具体使用,感兴趣的可以了解一下
    2023-08-08

最新评论