github.com/TeaOSLab/EdgeNode@v1.3.8/internal/utils/encrypt.go (about)

     1  // Copyright 2021 Liuxiangchao iwind.liu@gmail.com. All rights reserved.
     2  
     3  package utils
     4  
     5  import (
     6  	"bytes"
     7  	"crypto/aes"
     8  	"crypto/cipher"
     9  	"encoding/base64"
    10  	"encoding/json"
    11  	"errors"
    12  	"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
    13  	teaconst "github.com/TeaOSLab/EdgeNode/internal/const"
    14  	"github.com/TeaOSLab/EdgeNode/internal/events"
    15  	"github.com/iwind/TeaGo/logs"
    16  	"github.com/iwind/TeaGo/maps"
    17  	"github.com/iwind/TeaGo/rands"
    18  	stringutil "github.com/iwind/TeaGo/utils/string"
    19  )
    20  
    21  var (
    22  	defaultNodeEncryptKey    = rands.HexString(32)
    23  	defaultClusterEncryptKey = rands.HexString(32)
    24  )
    25  
    26  var encryptV2Suffix = []byte("$v2")
    27  
    28  func init() {
    29  	if !teaconst.IsMain {
    30  		return
    31  	}
    32  
    33  	events.On(events.EventReload, func() {
    34  		nodeConfig, _ := nodeconfigs.SharedNodeConfig()
    35  		if nodeConfig != nil {
    36  			defaultNodeEncryptKey = stringutil.Md5(nodeConfig.NodeId + "@" + nodeConfig.Secret)
    37  			if len(nodeConfig.ClusterSecret) == 0 {
    38  				defaultClusterEncryptKey = defaultNodeEncryptKey
    39  			} else {
    40  				defaultClusterEncryptKey = stringutil.Md5(nodeConfig.ClusterSecret)
    41  			}
    42  		}
    43  	})
    44  }
    45  
    46  // SimpleEncrypt 加密特殊信息
    47  func SimpleEncrypt(data []byte) []byte {
    48  	var method = &AES256CFBMethod{}
    49  	err := method.Init([]byte(defaultClusterEncryptKey), []byte(defaultClusterEncryptKey[:16]))
    50  	if err != nil {
    51  		logs.Println("[SimpleEncrypt]" + err.Error())
    52  		return data
    53  	}
    54  
    55  	dst, err := method.Encrypt(data)
    56  	if err != nil {
    57  		logs.Println("[SimpleEncrypt]" + err.Error())
    58  		return data
    59  	}
    60  	dst = append(dst, encryptV2Suffix...)
    61  	return dst
    62  }
    63  
    64  // SimpleDecrypt 解密特殊信息
    65  func SimpleDecrypt(data []byte) []byte {
    66  	if bytes.HasSuffix(data, encryptV2Suffix) {
    67  		data = data[:len(data)-len(encryptV2Suffix)]
    68  		return simpleDecrypt(data, defaultClusterEncryptKey)
    69  	}
    70  
    71  	// 兼容老的Key
    72  	return simpleDecrypt(data, defaultNodeEncryptKey)
    73  }
    74  
    75  func simpleDecrypt(data []byte, key string) []byte {
    76  	var method = &AES256CFBMethod{}
    77  	err := method.Init([]byte(key), []byte(key[:16]))
    78  	if err != nil {
    79  		logs.Println("[MagicKeyEncode]" + err.Error())
    80  		return data
    81  	}
    82  
    83  	src, err := method.Decrypt(data)
    84  	if err != nil {
    85  		logs.Println("[MagicKeyEncode]" + err.Error())
    86  		return data
    87  	}
    88  	return src
    89  }
    90  
    91  func SimpleEncryptMap(m maps.Map) (base64String string, err error) {
    92  	mJSON, err := json.Marshal(m)
    93  	if err != nil {
    94  		return "", err
    95  	}
    96  	var data = SimpleEncrypt(mJSON)
    97  	return base64.StdEncoding.EncodeToString(data), nil
    98  }
    99  
   100  func SimpleDecryptMap(base64String string) (maps.Map, error) {
   101  	data, err := base64.StdEncoding.DecodeString(base64String)
   102  	if err != nil {
   103  		return nil, err
   104  	}
   105  	var mJSON = SimpleDecrypt(data)
   106  	var result = maps.Map{}
   107  	err = json.Unmarshal(mJSON, &result)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  	return result, nil
   112  }
   113  
   114  func SimpleEncryptObject(ptr any) (string, error) {
   115  	mJSON, err := json.Marshal(ptr)
   116  	if err != nil {
   117  		return "", err
   118  	}
   119  	var data = SimpleEncrypt(mJSON)
   120  	return base64.StdEncoding.EncodeToString(data), nil
   121  }
   122  
   123  func SimpleDecryptObjet(base64String string, ptr any) error {
   124  	data, err := base64.StdEncoding.DecodeString(base64String)
   125  	if err != nil {
   126  		return err
   127  	}
   128  	var mJSON = SimpleDecrypt(data)
   129  	err = json.Unmarshal(mJSON, ptr)
   130  	return err
   131  }
   132  
   133  type AES256CFBMethod struct {
   134  	block cipher.Block
   135  	iv    []byte
   136  }
   137  
   138  func (this *AES256CFBMethod) Init(key, iv []byte) error {
   139  	// 判断key是否为32长度
   140  	var l = len(key)
   141  	if l > 32 {
   142  		key = key[:32]
   143  	} else if l < 32 {
   144  		key = append(key, bytes.Repeat([]byte{' '}, 32-l)...)
   145  	}
   146  
   147  	block, err := aes.NewCipher(key)
   148  	if err != nil {
   149  		return err
   150  	}
   151  	this.block = block
   152  
   153  	// 判断iv长度
   154  	var l2 = len(iv)
   155  	if l2 > aes.BlockSize {
   156  		iv = iv[:aes.BlockSize]
   157  	} else if l2 < aes.BlockSize {
   158  		iv = append(iv, bytes.Repeat([]byte{' '}, aes.BlockSize-l2)...)
   159  	}
   160  	this.iv = iv
   161  
   162  	return nil
   163  }
   164  
   165  func (this *AES256CFBMethod) Encrypt(src []byte) (dst []byte, err error) {
   166  	if len(src) == 0 {
   167  		return
   168  	}
   169  
   170  	defer func() {
   171  		var r = recover()
   172  		if r != nil {
   173  			err = errors.New("encrypt failed")
   174  		}
   175  	}()
   176  
   177  	dst = make([]byte, len(src))
   178  
   179  	var encrypter = cipher.NewCFBEncrypter(this.block, this.iv)
   180  	encrypter.XORKeyStream(dst, src)
   181  
   182  	return
   183  }
   184  
   185  func (this *AES256CFBMethod) Decrypt(dst []byte) (src []byte, err error) {
   186  	if len(dst) == 0 {
   187  		return
   188  	}
   189  
   190  	defer func() {
   191  		r := recover()
   192  		if r != nil {
   193  			err = errors.New("decrypt failed")
   194  		}
   195  	}()
   196  
   197  	src = make([]byte, len(dst))
   198  	var decrypter = cipher.NewCFBDecrypter(this.block, this.iv)
   199  	decrypter.XORKeyStream(src, dst)
   200  
   201  	return
   202  }