package mtwmapi import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/rand" "encoding/base64" "errors" "io" "log" "sync" ) //ip配置信息 type global struct { LocalHost string //本机内网IP RemoteHost string //远程端IP RemotePort string //远程端口 ServerList map[string]string ServerListLock sync.RWMutex } type commonConf struct { HttpPort string RPCPort string Cluster bool CryptoKey string } var ( GlobalSetting = &global{} CommonSetting = &commonConf{ HttpPort: "6000", RPCPort: "7000", Cluster: false, CryptoKey: "Adba723b7fe06819", } ) /* 以下为clientID相关逻辑 */ //对称加密IP和端口,当做clientId func GenClientId() string { raw := []byte(GlobalSetting.LocalHost + ":" + CommonSetting.RPCPort) //raw := []byte(hostStr) str, err := Encrypt(raw, []byte(CommonSetting.CryptoKey)) if err != nil { log.Fatal(err) } return str } func Encrypt(rawData, key []byte) (string, error) { data, err := aesCBCEncrypt(rawData, key) if err != nil { return "", err } return base64.StdEncoding.EncodeToString(data), nil } //AES加密 func aesCBCEncrypt(rawData, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return []byte{}, err } //填充原文 blockSize := block.BlockSize() rawData = pKCS7Padding(rawData, blockSize) //初始向量IV必须是唯一,但不需要保密 cipherText := make([]byte, blockSize+len(rawData)) //block大小 16 iv := cipherText[:blockSize] if _, err := io.ReadFull(rand.Reader, iv); err != nil { return []byte{}, err } //block大小和初始向量大小一定要一致 mode := cipher.NewCBCEncrypter(block, iv) mode.CryptBlocks(cipherText[blockSize:], rawData) return cipherText, nil } func DecryptDESECB(d, key []byte) string { data, err := base64.StdEncoding.DecodeString(string(d)) if err != nil { return "" } block, err := aes.NewCipher(key) if err != nil { return "" } bs := block.BlockSize() if len(data)%bs != 0 { return "" } out := make([]byte, len(data)) dst := out for len(data) > 0 { block.Decrypt(dst, data[:bs]) data = data[bs:] dst = dst[bs:] } out = PKCS5UnPadding(out) return string(out) } func PKCS5UnPadding(origData []byte) []byte { length := len(origData) unpadding := int(origData[length-1]) return origData[:(length - unpadding)] } func Decrypt(rawData string, key []byte) (string, error) { data, err := base64.StdEncoding.DecodeString(rawData) if err != nil { return "", err } dnData, err := aesCBCDncrypt(data, key) if err != nil { return "", err } return string(dnData), nil } //AES解密 func aesCBCDncrypt(encryptData, key []byte) ([]byte, error) { block, err := aes.NewCipher(key) if err != nil { return []byte{}, err } blockSize := block.BlockSize() if len(encryptData) < blockSize { return []byte{}, errors.New("ciphertext too short") } iv := encryptData[:blockSize] encryptData = encryptData[blockSize:] if len(encryptData)%blockSize != 0 { return []byte{}, errors.New("ciphertext is not a multiple of the block size") } mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(encryptData, encryptData) //解填充 encryptData, err = pKCS7UnPadding(encryptData) return encryptData, err } func pKCS7Padding(ciphertext []byte, blockSize int) []byte { padding := blockSize - len(ciphertext)%blockSize padText := bytes.Repeat([]byte{byte(padding)}, padding) return append(ciphertext, padText...) } func pKCS7UnPadding(origData []byte) ([]byte, error) { length := len(origData) unPadding := int(origData[length-1]) if length-unPadding < 0 || length-unPadding > len(origData) { return nil, errors.New("unPadding error") } return origData[:(length - unPadding)], nil }