106 lines
2.3 KiB
Go
106 lines
2.3 KiB
Go
|
package encoding
|
|||
|
|
|||
|
import (
|
|||
|
"bytes"
|
|||
|
"crypto/aes"
|
|||
|
"crypto/cipher"
|
|||
|
"encoding/base64"
|
|||
|
"encoding/json"
|
|||
|
"errors"
|
|||
|
)
|
|||
|
|
|||
|
//EncryptConfig 加密配置
|
|||
|
type EncryptConfig struct {
|
|||
|
Key string
|
|||
|
IV string
|
|||
|
}
|
|||
|
|
|||
|
//JSON JSON格式化增加对[]byte的支持
|
|||
|
func JSON(o interface{}) string {
|
|||
|
var v []byte
|
|||
|
switch o1 := o.(type) {
|
|||
|
case [][]byte:
|
|||
|
o2 := make([]interface{}, len(o1))
|
|||
|
for i := 0; i < len(o1); i++ {
|
|||
|
o2[i] = string(o1[i])
|
|||
|
}
|
|||
|
v, _ = json.Marshal(o2)
|
|||
|
case []interface{}:
|
|||
|
for i := 0; i < len(o1); i++ {
|
|||
|
if b, ok := o1[i].([]byte); ok {
|
|||
|
o1[i] = string(b)
|
|||
|
}
|
|||
|
}
|
|||
|
v, _ = json.Marshal(o1)
|
|||
|
default:
|
|||
|
v, _ = json.Marshal(o)
|
|||
|
}
|
|||
|
if len(v) > 0 {
|
|||
|
return string(v)
|
|||
|
}
|
|||
|
return ""
|
|||
|
}
|
|||
|
|
|||
|
//填充到BlockSize整数倍长度,如果正好就是对的长度,再多填充一个BlockSize长度
|
|||
|
func pad(src []byte) []byte {
|
|||
|
padding := aes.BlockSize - len(src)%aes.BlockSize
|
|||
|
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
|||
|
return append(src, padtext...)
|
|||
|
}
|
|||
|
|
|||
|
//去除填充的字节
|
|||
|
func unpad(src []byte) ([]byte, error) {
|
|||
|
length := len(src)
|
|||
|
if length == 0 {
|
|||
|
return []byte{0}, nil
|
|||
|
}
|
|||
|
unpadding := int(src[length-1])
|
|||
|
if unpadding > length {
|
|||
|
return nil, errors.New("unpad error. This could happen when incorrect encryption key is used")
|
|||
|
}
|
|||
|
return src[:(length - unpadding)], nil
|
|||
|
}
|
|||
|
|
|||
|
//Encrypt 加密
|
|||
|
func Encrypt(text string, c *EncryptConfig) (string, error) {
|
|||
|
if "" == text {
|
|||
|
return "", nil
|
|||
|
}
|
|||
|
block, err := aes.NewCipher([]byte(c.Key))
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
msg := pad([]byte(text))
|
|||
|
ciphertext := make([]byte, len(msg))
|
|||
|
mode := cipher.NewCBCEncrypter(block, []byte(c.IV))
|
|||
|
mode.CryptBlocks(ciphertext, msg)
|
|||
|
finalMsg := base64.StdEncoding.EncodeToString(ciphertext)
|
|||
|
return finalMsg, nil
|
|||
|
}
|
|||
|
|
|||
|
//Decrypt 解密
|
|||
|
func Decrypt(text string, c *EncryptConfig) (string, error) {
|
|||
|
if "" == text {
|
|||
|
return "", nil
|
|||
|
}
|
|||
|
block, err := aes.NewCipher([]byte(c.Key))
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
decodedMsg, err := base64.StdEncoding.DecodeString(text)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
if (len(decodedMsg) % aes.BlockSize) != 0 {
|
|||
|
return "", errors.New("blocksize must be multipe of decoded message length")
|
|||
|
}
|
|||
|
msg := decodedMsg
|
|||
|
mode := cipher.NewCBCDecrypter(block, []byte(c.IV))
|
|||
|
mode.CryptBlocks(msg, msg)
|
|||
|
unpadMsg, err := unpad(msg)
|
|||
|
if err != nil {
|
|||
|
return "", err
|
|||
|
}
|
|||
|
return string(unpadMsg), nil
|
|||
|
}
|