/
encoding_aes.go
122 lines (104 loc) · 2.91 KB
/
encoding_aes.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
package cmn
import (
"bytes"
"crypto/aes"
"errors"
)
// 对称加密结构体
type AesEcb struct {
secret []byte
}
// 创建指定密码的对称加密对象
func NewAesEcb(secret string) *AesEcb {
return &AesEcb{secret: StringToBytes(secret)}
}
// 字符串加密
func (a *AesEcb) Encode(src string) (string, error) {
by, err := a.EncodeBytes(StringToBytes(src), a.secret)
if err != nil {
return "", err
}
return Base64(by), nil
}
// 字符串解密
func (a *AesEcb) Decode(src string) (string, error) {
srcBy, err := Base64Decode(src)
if err != nil {
return "", err
}
by, err := a.DecodeBytes(srcBy, a.secret)
if err != nil {
return "", err
}
return BytesToString(by), nil
}
// 字节数组加密
func (a *AesEcb) EncodeBytes(src []byte, secret []byte) ([]byte, error) {
if len(src) == 0 {
return src, nil // 空内容加密结果仍旧空
}
appendkeys := StringToBytes("秘钥长度仅支持16位、24位、32位,如果参数的秘钥有误,则按默认补足至32位方便使用")
if !checkKey(secret) {
secret = append(secret, appendkeys...)[:32]
}
block, err := aes.NewCipher(secret)
if err != nil {
return nil, err
}
paddingSrc := aesPkcs5Padding(src, block.BlockSize())
var dst []byte
tmpData := make([]byte, block.BlockSize())
for index := 0; index < len(paddingSrc); index += block.BlockSize() {
block.Encrypt(tmpData, paddingSrc[index:index+block.BlockSize()])
dst = append(dst, tmpData...)
}
return dst, nil
}
// 字节数组解密
func (a *AesEcb) DecodeBytes(src []byte, secret []byte) ([]byte, error) {
if len(src) == 0 {
return src, nil // 空内容加密结果仍旧空
}
appendkeys := StringToBytes("秘钥长度仅支持16位、24位、32位,如果参数的秘钥有误,则按默认补足至32位方便使用")
if !checkKey(secret) {
secret = append(secret, appendkeys...)[:32]
}
block, err := aes.NewCipher(secret)
if err != nil {
return nil, err
}
if len(src)%block.BlockSize() != 0 {
return nil, errors.New("源数据长度有误无法解密")
}
var dst []byte
tmpData := make([]byte, block.BlockSize())
for index := 0; index < len(src); index += block.BlockSize() {
block.Decrypt(tmpData, src[index:index+block.BlockSize()])
dst = append(dst, tmpData...)
}
dst, err = aesPpkcs5UnPadding(dst)
if err != nil {
return nil, err
}
return dst, nil
}
// PKCS5填充
func aesPkcs5Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
// 去除PKCS5填充
func aesPpkcs5UnPadding(origData []byte) ([]byte, error) {
length := len(origData)
unpadding := int(origData[length-1])
if length < unpadding {
return nil, errors.New("invalid unpadding length")
}
return origData[:(length - unpadding)], nil
}
// 秘钥长度验证
func checkKey(key []byte) bool {
n := len(key)
return n == 16 || n == 24 || n == 32
}