Golang的Aes加解密工具类

package main

import (
	"bytes"
	"crypto/aes"
	"crypto/sha1"
	"encoding/binary"
	"encoding/hex"
	"fmt"
)

// SHA1PRNG 模拟Java的SHA1PRNG算法
type SHA1PRNG struct {
	state   [sha1.Size]byte
	counter uint32
	index   int
}

// NewSHA1PRNG 使用种子初始化SHA1PRNG
func NewSHA1PRNG(seed []byte) *SHA1PRNG {
	prng := &SHA1PRNG{}
	prng.reseed(seed)
	return prng
}

func (prng *SHA1PRNG) reseed(seed []byte) {
	prng.index = 0
	prng.counter = 0
	seedHash := sha1.Sum(seed)
	prng.state = sha1.Sum(seedHash[:]) // 两次哈希模拟Java的初始化
}

// Read 生成随机字节
func (prng *SHA1PRNG) Read(p []byte) (n int, err error) {
	for i := range p {
		if prng.index >= sha1.Size {
			prng.generateNewState()
		}
		p[i] = prng.state[prng.index]
		prng.index++
	}
	return len(p), nil
}

func (prng *SHA1PRNG) generateNewState() {
	buffer := make([]byte, sha1.Size+4)
	copy(buffer, prng.state[:])
	binary.BigEndian.PutUint32(buffer[sha1.Size:], prng.counter)
	newState := sha1.Sum(buffer)
	prng.state = newState
	prng.counter++
	prng.index = 0
}

// generateAESKey 生成AES密钥
func generateAESKey(key string) []byte {
	prng := NewSHA1PRNG([]byte(key))
	keyBytes := make([]byte, 16) // 128位密钥
	prng.Read(keyBytes)
	return keyBytes
}

// pkcs5Pad PKCS5填充
func pkcs5Pad(data []byte, blockSize int) []byte {
	padding := blockSize - (len(data) % blockSize)
	padText := bytes.Repeat([]byte{byte(padding)}, padding)
	return append(data, padText...)
}

// pkcs5Unpad 去除PKCS5填充
func pkcs5Unpad(data []byte) []byte {
	length := len(data)
	if length == 0 {
		return data
	}
	padding := int(data[length-1])
	if padding < 1 || padding > length {
		return data
	}
	return data[:length-padding]
}

// encrypt AES加密(ECB模式)
func encrypt(data []byte, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	data = pkcs5Pad(data, blockSize)
	encrypted := make([]byte, len(data))
	for i := 0; i < len(data); i += blockSize {
		block.Encrypt(encrypted[i:i+blockSize], data[i:i+blockSize])
	}
	return encrypted, nil
}

// decrypt AES解密(ECB模式)
func decrypt(data []byte, key []byte) ([]byte, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	blockSize := block.BlockSize()
	if len(data)%blockSize != 0 {
		return nil, fmt.Errorf("input not full blocks")
	}
	decrypted := make([]byte, len(data))
	for i := 0; i < len(data); i += blockSize {
		block.Decrypt(decrypted[i:i+blockSize], data[i:i+blockSize])
	}
	return pkcs5Unpad(decrypted), nil
}

// parseByte2HexStr 字节转16进制字符串
func parseByte2HexStr(data []byte) string {
	return hex.EncodeToString(data)
}

// parseHexStr2Byte 16进制字符串转字节
func parseHexStr2Byte(hexStr string) ([]byte, error) {
	return hex.DecodeString(hexStr)
}

// EncryptToStr 加密字符串
func EncryptToStr(data, key string) (string, error) {
	if data == "" {
		return "", nil
	}
	aesKey := generateAESKey(key)
	encrypted, err := encrypt([]byte(data), aesKey)
	if err != nil {
		return "", err
	}
	return parseByte2HexStr(encrypted), nil
}

// DecryptToStr 解密字符串
func DecryptToStr(enCryptdata, key string) (string, error) {
	if enCryptdata == "" {
		return "", nil
	}
	data, err := parseHexStr2Byte(enCryptdata)
	if err != nil {
		return "", err
	}
	aesKey := generateAESKey(key)
	decrypted, err := decrypt(data, aesKey)
	if err != nil {
		return "", err
	}
	return string(decrypted), nil
}

你可能感兴趣的:(golang,开发语言,后端)