/
encryptionService.go
151 lines (136 loc) · 3.74 KB
/
encryptionService.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package gree
import (
"bytes"
"crypto/aes"
"encoding/base64"
"encoding/json"
"fmt"
"github.com/labstack/gommon/log"
)
var defaultKey = "a3K8Bx%2r8Y7#xDh"
type DeviceInfo struct {
T string `json:"t"`
Cid string `json:"cid"`
Bc string `json:"bc"`
Brand string `json:"brand"`
Catalog string `json:"catalog"`
Mac string `json:"mac"`
Mid string `json:"mid"`
Model string `json:"model"`
Name string `json:"name"`
Lock int `json:"lock"`
Series string `json:"series"`
Vender string `json:"vender"`
Ver string `json:"ver"`
Key string `json:"key"`
Dat []int `json:"dat"`
Cols []string `json:"cols"`
Val []int `json:"val"`
P []int `json:"p"`
R int `json:"r"`
Opt []string `json:"opt"`
}
func Decrypt(input UDPInfo, key string) DeviceInfo {
if key == "" {
key = defaultKey
}
deviceInfo := DeviceInfo{}
decodeString, err := base64.StdEncoding.DecodeString(input.Pack)
if err != nil {
log.Errorf("[BASE64] base64解码失败:%s", err)
return DeviceInfo{}
}
decrypted, err := ECBDecrypt(decodeString, []byte(key))
if err != nil {
log.Errorf("[KEY] 解密失败:%s", err)
return deviceInfo
}
err = json.Unmarshal(decrypted, &deviceInfo)
if err != nil {
log.Errorf("[JSON] json失败:%s", err)
}
return deviceInfo
}
func Encrypt(output interface{}, key string) string {
if key == "" {
key = defaultKey
}
marshal, err := json.Marshal(output)
if err != nil {
log.Errorf("[JSON] json序列化失败:%s", err)
return ""
}
encrypted, _ := ECBEncrypt(marshal, []byte(key))
return base64.StdEncoding.EncodeToString(encrypted)
}
func ECBDecrypt(crypted, key []byte) ([]byte, error) {
if !validKey(key) {
return nil, fmt.Errorf("秘钥长度错误,当前传入长度为 %d", len(key))
}
if len(crypted) < 1 {
return nil, fmt.Errorf("源数据长度不能为0")
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(crypted)%block.BlockSize() != 0 {
return nil, fmt.Errorf("源数据长度必须是 %d 的整数倍,当前长度为:%d", block.BlockSize(), len(crypted))
}
var dst []byte
tmpData := make([]byte, block.BlockSize())
for index := 0; index < len(crypted); index += block.BlockSize() {
block.Decrypt(tmpData, crypted[index:index+block.BlockSize()])
dst = append(dst, tmpData...)
}
dst, err = PKCS5UnPadding(dst)
if err != nil {
return nil, err
}
return dst, nil
}
func ECBEncrypt(src, key []byte) ([]byte, error) {
if !validKey(key) {
return nil, fmt.Errorf("秘钥长度错误, 当前传入长度为 %d", len(key))
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
if len(src) < 1 {
return nil, fmt.Errorf("源数据长度不能为0")
}
src = PKCS5Padding(src, block.BlockSize())
if len(src)%block.BlockSize() != 0 {
return nil, fmt.Errorf("源数据长度必须是 %d 的整数倍,当前长度为:%d", block.BlockSize(), len(src))
}
var dst []byte
tmpData := make([]byte, block.BlockSize())
for index := 0; index < len(src); index += block.BlockSize() {
block.Encrypt(tmpData, src[index:index+block.BlockSize()])
dst = append(dst, tmpData...)
}
return dst, nil
}
func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
func PKCS5UnPadding(origData []byte) ([]byte, error) {
length := len(origData)
unpadding := int(origData[length-1])
if length < unpadding {
return nil, fmt.Errorf("invalid unpadding length")
}
return origData[:(length - unpadding)], nil
}
func validKey(key []byte) bool {
k := len(key)
switch k {
default:
return false
case 16, 24, 32:
return true
}
}