aes.go 2.62 KB
package components

import (
	"bytes"
	"crypto/aes"
	"crypto/cipher"
	"encoding/base64"
	"errors"
)

var (
	PwdKey = []byte("luluszhaozhaoAAA") //RC4 zhaolu2333
)

type AesEncipher struct {
}

func NewAesEncipher() IEncipher {
	return &AesEncipher{}
}

//pkcs7Padding 填充
func (a *AesEncipher) pkcs7Padding(data []byte, blockSize int) []byte {
	//判断缺少几位长度。最少1,最多 blockSize
	padding := blockSize - len(data)%blockSize
	//补足位数。把切片[]byte{byte(padding)}复制padding个
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padText...)
}

//pkcs7UnPadding 填充的反向操作
func (a *AesEncipher) pkcs7UnPadding(data []byte) ([]byte, error) {
	length := len(data)
	if length == 0 {
		return nil, errors.New("加密字符串错误!")
	}
	//获取填充的个数
	unPadding := int(data[length-1])
	return data[:(length - unPadding)], nil
}

//AesEncrypt 加密
func (a *AesEncipher) Encrypt(data []byte) ([]byte, error) {
	//创建加密实例
	block, err := aes.NewCipher(PwdKey)
	if err != nil {
		return nil, err
	}
	//判断加密快的大小
	blockSize := block.BlockSize()
	//填充
	encryptBytes := a.pkcs7Padding(data, blockSize)
	if len(encryptBytes)%blockSize != 0 {
		return nil, errors.New("crypto/cipher: input not full blocks")
	}
	//初始化加密数据接收切片
	crypted := make([]byte, len(encryptBytes))
	//使用cbc加密模式
	blockMode := cipher.NewCBCEncrypter(block, PwdKey[:blockSize])
	//执行加密
	blockMode.CryptBlocks(crypted, encryptBytes)
	return crypted, nil
}

//AesDecrypt 解密
func (a *AesEncipher) Decrypt(data []byte) ([]byte, error) {
	//创建实例
	block, err := aes.NewCipher(PwdKey)
	if err != nil {
		return nil, err
	}
	//获取块的大小
	blockSize := block.BlockSize()
	//使用cbc
	blockMode := cipher.NewCBCDecrypter(block, PwdKey[:blockSize])
	//初始化解密数据接收切片
	dataLen := len(data)
	if dataLen%blockSize != 0 {
		return nil, errors.New("crypto/cipher: input not full blocks")
	}
	crypted := make([]byte, dataLen)
	//执行解密
	blockMode.CryptBlocks(crypted, data)
	//去除填充
	crypted, err = a.pkcs7UnPadding(crypted)
	if err != nil {
		return nil, err
	}
	return crypted, nil
}

//EncryptByAes Aes加密 后 base64 再加
func (a *AesEncipher) EncryptByAes(data []byte) (string, error) {
	res, err := a.Encrypt(data)
	if err != nil {
		return "", err
	}
	return base64.StdEncoding.EncodeToString(res), nil
}

//DecryptByAes Aes 解密
func (a *AesEncipher) DecryptByAes(data string) ([]byte, error) {
	dataByte, err := base64.StdEncoding.DecodeString(data)
	if err != nil {
		return nil, err
	}
	return a.Decrypt(dataByte)
}