| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 | package cryptoimport (	"context"	"crypto/aes"	"crypto/cipher"	"crypto/rand"	"encoding/base64"	"encoding/json"	"io"	"reflect"	"github.com/0xJacky/Nginx-UI/settings"	"gorm.io/gorm/schema")// AesEncrypt encrypts text and given key with AES.func AesEncrypt(text []byte) ([]byte, error) {	if len(text) == 0 {		return nil, ErrPlainTextEmpty	}	block, err := aes.NewCipher(settings.CryptoSettings.GetSecretMd5())	if err != nil {		return nil, err	}	b := base64.StdEncoding.EncodeToString(text)	ciphertext := make([]byte, aes.BlockSize+len(b))	iv := ciphertext[:aes.BlockSize]	if _, err = io.ReadFull(rand.Reader, iv); err != nil {		return nil, err	}	cfb := cipher.NewCFBEncrypter(block, iv)	cfb.XORKeyStream(ciphertext[aes.BlockSize:], []byte(b))	return ciphertext, nil}// AesDecrypt decrypts text and given key with AES.func AesDecrypt(text []byte) ([]byte, error) {	block, err := aes.NewCipher(settings.CryptoSettings.GetSecretMd5())	if err != nil {		return nil, err	}	if len(text) < aes.BlockSize {		return nil, ErrCipherTextTooShort	}	iv := text[:aes.BlockSize]	text = text[aes.BlockSize:]	cfb := cipher.NewCFBDecrypter(block, iv)	cfb.XORKeyStream(text, text)	data, err := base64.StdEncoding.DecodeString(string(text))	if err != nil {		return nil, err	}	return data, nil}type JSONAesSerializer struct{}func (JSONAesSerializer) Scan(ctx context.Context, field *schema.Field, dst reflect.Value, dbValue interface{}) (err error) {	fieldValue := reflect.New(field.FieldType)	if dbValue != nil {		var bytes []byte		switch v := dbValue.(type) {		case []byte:			bytes = v		case string:			bytes = []byte(v)		default:			bytes, err = json.Marshal(v)			if err != nil {				return err			}		}		if len(bytes) > 0 {			bytes, err = AesDecrypt(bytes)			if err != nil {				return err			}			err = json.Unmarshal(bytes, fieldValue.Interface())		}	}	field.ReflectValueOf(ctx, dst).Set(fieldValue.Elem())	return}// Value implements serializer interfacefunc (JSONAesSerializer) Value(ctx context.Context, field *schema.Field, dst reflect.Value, fieldValue interface{}) (interface{}, error) {	result, err := json.Marshal(fieldValue)	if string(result) == "null" {		if field.TagSettings["NOT NULL"] != "" {			return "", nil		}		return nil, err	}	encrypt, err := AesEncrypt(result)	return string(encrypt), err}
 |