欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-18 11:54:38
aes加密aes对称加密简介aes是一个对称密码,旨在取代des成为广泛使用的标准。是美国联邦*采用的一种区块加密标准。aes对称加密过程加密解密算法的输入是一个128位分组。这些分组被描述成4×4...

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 AES 加密