package utils import ( "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" "encoding/binary" "fmt" ) type Crypto struct { } // DecryptKey 解密处理函数 func (c Crypto) DecryptKey(data, iv, key string) (string, Error) { info, err := c.aesCBCDecryptKey(data, iv, key) if err != nil { return "", err } return info, nil } func (c Crypto) aesCBCDecryptKey(data, iv, key string) (string, Error) { cipherByte, err := base64.StdEncoding.DecodeString(data) if err != nil { Logger.Error(err) return "", ErrorEncryptBase64Error } k := []byte(key) // 分组密钥 block, err := aes.NewCipher(k) if err != nil { Logger.Error(err) return "", ErrorEncryptBase64Error } if len(iv) < 16 { return "", ErrorEncryptBase64Error } // 加密模式 blockMode := cipher.NewCBCDecrypter(block, []byte(iv)) // 创建数组 origData := make([]byte, len(cipherByte)) // 解密 blockMode.CryptBlocks(origData, cipherByte) // 去补码 origData = c.pKCS7UnPadding(origData) return string(origData), nil } // Decrypt 解密处理函数 func (c Crypto) Decrypt(data, iv string) (string, Error) { info, err := c.aesCBCDecrypt(data, iv) if err != nil { return "", err } return info, nil } func (c Crypto) aesCBCDecrypt(data, iv string) (string, Error) { key := c.GetKey() cipherByte, err := base64.StdEncoding.DecodeString(data) if err != nil { Logger.Error(err) return "", ErrorEncryptBase64Error } k := []byte(key) // 分组密钥 block, err := aes.NewCipher(k) if err != nil { Logger.Error(err) return "", ErrorEncryptBase64Error } if len(iv) < 16 { return "", ErrorEncryptBase64Error } // 加密模式 blockMode := cipher.NewCBCDecrypter(block, []byte(iv)) // 创建数组 origData := make([]byte, len(cipherByte)) // 解密 blockMode.CryptBlocks(origData, cipherByte) // 去补码 origData = c.pKCS7UnPadding(origData) return string(origData), nil } func (c Crypto) GetKey() string { return GetConfigString("encrypt.encrypt_key") } // PKCS7UnPadding 去码 func (c Crypto) pKCS7UnPadding(origData []byte) []byte { length := len(origData) if length == 0 { return nil } unPadding := int(origData[length-1]) if length < unPadding { return nil } return origData[:(length - unPadding)] } func (c Crypto) pKCS7Padding(ciphertext []byte, blockSize int) []byte { // 判断缺少几位长度,最少为 1,最多为 blockSize padding := blockSize - len(ciphertext)%blockSize // 补足位数,把切片 []byte{byte(padding)} 复制 padding 个 padtext := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padtext...) } // Encrypt 加密 func (c Crypto) Encrypt(data []byte) (map[string]string, Error) { info, err := c.aesCBCEncrypt(data) if err != nil { return nil, err } return info, nil } func (c Crypto) aesCBCEncrypt(data []byte) (map[string]string, Error) { key := c.GetKey() k := []byte(key) iv := GetRandString(NumberSixteen) // 分组密钥 block, err := aes.NewCipher(k) if err != nil { return nil, ErrorEncryptAesKeyError } // 获取密钥块的长度 blockSize := block.BlockSize() // 补充码 data = c.pKCS7Padding(data, blockSize) // 加密模式 blockMode := cipher.NewCBCEncrypter(block, []byte(iv)) // 创建数组 crypted := make([]byte, len(data)) // 加密 blockMode.CryptBlocks(crypted, data) return map[string]string{ "data": base64.StdEncoding.EncodeToString(crypted), "iv": iv, }, nil } // Encrypt 加密 func (c Crypto) EncryptKey(data []byte, key string) (map[string]string, Error) { info, err := c.aesCBCEncryptKey(data, key) if err != nil { return nil, err } return info, nil } func (c Crypto) aesCBCEncryptKey(data []byte, key string) (map[string]string, Error) { k := []byte(key) iv := GetRandString(NumberSixteen) // 分组密钥 block, err := aes.NewCipher(k) if err != nil { return nil, ErrorEncryptAesKeyError } // 获取密钥块的长度 blockSize := block.BlockSize() // 补充码 data = c.pKCS7Padding(data, blockSize) // 加密模式 blockMode := cipher.NewCBCEncrypter(block, []byte(iv)) // 创建数组 crypted := make([]byte, len(data)) // 加密 blockMode.CryptBlocks(crypted, data) return map[string]string{ "data": base64.StdEncoding.EncodeToString(crypted), "iv": iv, }, nil } // AESEncryptECB 不使用IV的AES-ECB加密 // key长度必须为16、24或32字节,对应AES-128、AES-192、AES-256 func (c Crypto) AESEncryptECB(data string) (string, Error) { key := GetConfigString("encrypt.data_key") block, err := aes.NewCipher([]byte(key)) if err != nil { return "", ErrorEncryptMissingKey } // 检查密钥长度 keyLen := len(key) if keyLen != 16 && keyLen != 24 && keyLen != 32 { return "", ErrorEncryptMissingKey } dataByte := []byte(data) // 填充数据以适应块大小 dataByte = c.pKCS7Padding(dataByte, block.BlockSize()) // ECB模式加密 crypted := make([]byte, len(dataByte)) bs := block.BlockSize() for i := 0; i < len(dataByte); i += bs { block.Encrypt(crypted[i:i+bs], dataByte[i:i+bs]) } return base64.StdEncoding.EncodeToString(crypted), nil } // AESDecryptECB 不使用IV的AES-ECB解密 // key长度必须为16、24或32字节,对应AES-128、AES-192、AES-256 func (c Crypto) AESDecryptECB(data string) (string, Error) { if len([]byte(data)) < 16 { return "", ErrorEncryptMissingKey } key := GetConfigString("encrypt.data_key") block, err := aes.NewCipher([]byte(key)) if err != nil { return "", ErrorEncryptMissingKey } // 检查密钥长度 keyLen := len(key) if keyLen != 16 && keyLen != 24 && keyLen != 32 { return "", ErrorEncryptMissingKey } dataByte, err := base64.StdEncoding.DecodeString(data) if err != nil { Logger.Error(err) return "", ErrorEncryptBase64Error } // ECB模式解密 decrypted := make([]byte, len(dataByte)) bs := block.BlockSize() // 修复:正确 ECB 循环 for i := 0; i < len(dataByte); i += bs { block.Decrypt(decrypted[i:i+bs], dataByte[i:i+bs]) } // 移除填充 return string(c.pKCS7UnPadding(decrypted)), nil } func (c Crypto) DecryptWechatMsg(msgEncrypt string, encodingAESKey string) (msg []byte, receiveId string, err error) { aesKey, err := base64.StdEncoding.DecodeString(encodingAESKey + "=") if err != nil { return nil, "", fmt.Errorf("AESKey解码失败: %v", err) } // 1. Base64 解码密文 aesMsg, err := base64.StdEncoding.DecodeString(msgEncrypt) if err != nil { return nil, "", fmt.Errorf("base64解码失败: %v", err) } // 2. AES 解密(ECB + PKCS7) randMsg, err := c.aesDecrypt(aesMsg, aesKey) if err != nil { return nil, "", fmt.Errorf("aes解密失败: %v", err) } // 3. 去掉前16随机字节 content := randMsg[16:] if len(content) < 4 { return nil, "", fmt.Errorf("数据格式非法") } // 4. 读取4字节消息长度 msgLen := binary.BigEndian.Uint32(content[:4]) end := 4 + msgLen if uint32(len(content)) < end { return nil, "", fmt.Errorf("消息长度非法") } // 5. 截取消息体 msg = content[4:end] // 6. 剩余为 receiveid receiveId = string(content[end:]) return msg, receiveId, nil } // aesDecrypt AES-ECB-PKCS7 解密(微信加密标准) func (c Crypto) aesDecrypt(cipherText, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return nil, err } // ECB 模式 mode := cipher.NewCBCDecrypter(block, make([]byte, aes.BlockSize)) plainText := make([]byte, len(cipherText)) mode.CryptBlocks(plainText, cipherText) // PKCS7 去填充 return c.pKCS7UnPadding(plainText), nil }