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的Aes加解密工具类
最新推荐文章于 2025-10-15 19:26:58 发布
520

被折叠的 条评论
为什么被折叠?



