-
Notifications
You must be signed in to change notification settings - Fork 18
/
Crypto.go
80 lines (67 loc) · 1.68 KB
/
Crypto.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
package S
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"io"
"github.com/vmihailenco/msgpack/v5"
"github.com/jxskiss/base62"
"github.com/kokizzu/gotro/L"
)
// symmetric cryptography for string using golang
func createKey(key string) cipher.Block {
if key == `` {
key = `1234567890abcdef`
}
kLen := len(key)
if kLen < 16 {
for len(key) < 16 {
key += key
}
key = key[:16]
} else if kLen < 24 {
for len(key) < 24 {
key += key
}
key = key[:24]
} else if kLen < 32 {
for len(key) < 32 {
key += key
}
key = key[:32]
} else if kLen > 32 {
key = key[:32]
}
block, err := aes.NewCipher([]byte(key))
L.PanicIf(err, `aes.NewCipher`)
return block
}
func EncryptAES(in any, key string) (encryptedStr string) {
block := createKey(key)
plaintext, err := msgpack.Marshal(in)
L.PanicIf(err, `msgpack.Marshal`)
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
_, err = io.ReadFull(rand.Reader, iv)
L.PanicIf(err, `io.ReadFull rand.Reader`)
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
// convert to base64
return base62.EncodeToString(ciphertext)
}
func DecryptAES(encryptedStr, key string, out any) bool {
block := createKey(key)
ciphertext, err := base62.DecodeString(encryptedStr)
if L.IsError(err, `base64.DecodeString`) {
return false
}
if len(ciphertext) < aes.BlockSize {
return false
}
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
stream := cipher.NewCFBDecrypter(block, iv)
stream.XORKeyStream(ciphertext, ciphertext)
err = msgpack.Unmarshal(ciphertext, out)
return !L.IsError(err, `msgpack.Unmarshal`)
}