103 lines
2.2 KiB
Go
103 lines
2.2 KiB
Go
|
package mycrypto
|
|||
|
|
|||
|
import (
|
|||
|
"bytes"
|
|||
|
"crypto/aes"
|
|||
|
"crypto/cipher"
|
|||
|
"encoding/hex"
|
|||
|
"fmt"
|
|||
|
)
|
|||
|
|
|||
|
var (
|
|||
|
defaultAes256Cbc *Aes256Cbc
|
|||
|
)
|
|||
|
|
|||
|
type Aes256Cbc struct {
|
|||
|
Iv []byte // iv向量 (key 32字节 256位)
|
|||
|
Key []byte // 加密密钥 (iv 16字节 128位)
|
|||
|
}
|
|||
|
|
|||
|
func NewAes256Cbc(key, iv string) *Aes256Cbc {
|
|||
|
if len(key) != 32 {
|
|||
|
panic("密钥key长度应为32")
|
|||
|
}
|
|||
|
|
|||
|
if len(iv) != aes.BlockSize {
|
|||
|
panic("iv长度应为16")
|
|||
|
}
|
|||
|
return &Aes256Cbc{
|
|||
|
Iv: []byte(iv),
|
|||
|
Key: []byte(key),
|
|||
|
}
|
|||
|
}
|
|||
|
func InitAes256Cbc(key, iv string) {
|
|||
|
defaultAes256Cbc = NewAes256Cbc(key, iv)
|
|||
|
}
|
|||
|
|
|||
|
func Aes256CbcEncrypt(plainText string) (string, error) {
|
|||
|
return defaultAes256Cbc.Encrypt(plainText)
|
|||
|
}
|
|||
|
|
|||
|
func Aes256CbcDecrypt(cipherText string) (string, error) {
|
|||
|
return defaultAes256Cbc.Decrypt(cipherText)
|
|||
|
}
|
|||
|
|
|||
|
// Encrypt 加密
|
|||
|
func (a *Aes256Cbc) Encrypt(plainText string) (res string, err error) {
|
|||
|
defer func() {
|
|||
|
if err2 := recover(); err2 != nil {
|
|||
|
err = fmt.Errorf("panic: %s", err2)
|
|||
|
}
|
|||
|
}()
|
|||
|
|
|||
|
// PKCS5填充,补齐数据块
|
|||
|
bPlaintext := a.PKCS5Padding([]byte(plainText), aes.BlockSize)
|
|||
|
block, err := aes.NewCipher(a.Key)
|
|||
|
if err != nil {
|
|||
|
return plainText, err
|
|||
|
}
|
|||
|
|
|||
|
ciphertext := make([]byte, len(bPlaintext))
|
|||
|
mode := cipher.NewCBCEncrypter(block, a.Iv)
|
|||
|
mode.CryptBlocks(ciphertext, bPlaintext)
|
|||
|
|
|||
|
return hex.EncodeToString(ciphertext), nil
|
|||
|
}
|
|||
|
|
|||
|
// Decrypt 解密
|
|||
|
func (a *Aes256Cbc) Decrypt(cipherText string) (res string, err error) {
|
|||
|
defer func() {
|
|||
|
if err2 := recover(); err2 != nil {
|
|||
|
err = fmt.Errorf("panic: %s", err2)
|
|||
|
}
|
|||
|
}()
|
|||
|
|
|||
|
block, err := aes.NewCipher(a.Key)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
decodeString, err := hex.DecodeString(cipherText)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
|
|||
|
mode := cipher.NewCBCDecrypter(block, a.Iv)
|
|||
|
mode.CryptBlocks(decodeString, decodeString)
|
|||
|
|
|||
|
// 移除多余填充的补充位
|
|||
|
return string(a.PKCS5UnPadding(decodeString)), nil
|
|||
|
}
|
|||
|
|
|||
|
func (a *Aes256Cbc) PKCS5Padding(ciphertext []byte, blockSize int) []byte {
|
|||
|
padding := blockSize - len(ciphertext)%blockSize
|
|||
|
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
|||
|
return append(ciphertext, padtext...)
|
|||
|
}
|
|||
|
|
|||
|
func (a *Aes256Cbc) PKCS5UnPadding(src []byte) []byte {
|
|||
|
length := len(src)
|
|||
|
unpadding := int(src[length-1])
|
|||
|
return src[:(length - unpadding)]
|
|||
|
}
|