-
Notifications
You must be signed in to change notification settings - Fork 4
/
aes.go
246 lines (201 loc) · 6.18 KB
/
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
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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
package xcrypto
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"github.com/fufuok/utils"
"github.com/fufuok/utils/base58"
)
// AesCBCEnStringHex 加密, ZerosPadding
func AesCBCEnStringHex(s string, key []byte) string {
return hex.EncodeToString(AesCBCEncrypt(false, utils.S2B(s), key))
}
// AesCBCEnPKCS7StringHex 加密, Pkcs7Padding
func AesCBCEnPKCS7StringHex(s string, key []byte) string {
return hex.EncodeToString(AesCBCEncrypt(true, utils.S2B(s), key))
}
// AesCBCEnHex 加密, ZerosPadding
func AesCBCEnHex(b, key []byte) string {
return hex.EncodeToString(AesCBCEncrypt(false, b, key))
}
// AesCBCEnPKCS7Hex 加密, Pkcs7Padding
func AesCBCEnPKCS7Hex(b, key []byte) string {
return hex.EncodeToString(AesCBCEncrypt(true, b, key))
}
// AesCBCDeStringHex 解密, ZerosPadding
func AesCBCDeStringHex(s string, key []byte) string {
return utils.B2S(AesCBCDeHex(s, key))
}
// AesCBCDePKCS7StringHex 解密, Pkcs7Padding
func AesCBCDePKCS7StringHex(s string, key []byte) string {
return utils.B2S(AesCBCDePKCS7Hex(s, key))
}
// AesCBCDeHex 解密, ZerosPadding
func AesCBCDeHex(s string, key []byte) []byte {
if data, err := hex.DecodeString(s); err == nil {
return AesCBCDecrypt(false, data, key)
}
return nil
}
// AesCBCDePKCS7Hex 解密, Pkcs7Padding
func AesCBCDePKCS7Hex(s string, key []byte) []byte {
if data, err := hex.DecodeString(s); err == nil {
return AesCBCDecrypt(true, data, key)
}
return nil
}
// AesCBCEnStringB58 加密, ZerosPadding
func AesCBCEnStringB58(s string, key []byte) string {
return base58.Encode(AesCBCEncrypt(false, utils.S2B(s), key))
}
// AesCBCEnPKCS7StringB58 加密, Pkcs7Padding
func AesCBCEnPKCS7StringB58(s string, key []byte) string {
return base58.Encode(AesCBCEncrypt(true, utils.S2B(s), key))
}
// AesCBCEnB58 加密, ZerosPadding
func AesCBCEnB58(b, key []byte) string {
return base58.Encode(AesCBCEncrypt(false, b, key))
}
// AesCBCEnPKCS7B58 加密, Pkcs7Padding
func AesCBCEnPKCS7B58(b, key []byte) string {
return base58.Encode(AesCBCEncrypt(true, b, key))
}
// AesCBCDeStringB58 解密, ZerosPadding
func AesCBCDeStringB58(s string, key []byte) string {
return utils.B2S(AesCBCDeB58(s, key))
}
// AesCBCDePKCS7StringB58 解密, Pkcs7Padding
func AesCBCDePKCS7StringB58(s string, key []byte) string {
return utils.B2S(AesCBCDePKCS7B58(s, key))
}
// AesCBCDeB58 解密, ZerosPadding
func AesCBCDeB58(s string, key []byte) []byte {
return AesCBCDecrypt(false, base58.Decode(s), key)
}
// AesCBCDePKCS7B58 解密, Pkcs7Padding
func AesCBCDePKCS7B58(s string, key []byte) []byte {
return AesCBCDecrypt(true, base58.Decode(s), key)
}
// AesCBCEnStringB64 加密, ZerosPadding
func AesCBCEnStringB64(s string, key []byte) string {
return utils.B64UrlEncode(AesCBCEncrypt(false, utils.S2B(s), key))
}
// AesCBCEnPKCS7StringB64 加密, Pkcs7Padding
func AesCBCEnPKCS7StringB64(s string, key []byte) string {
return utils.B64UrlEncode(AesCBCEncrypt(true, utils.S2B(s), key))
}
// AesCBCEnB64 加密, ZerosPadding
func AesCBCEnB64(b, key []byte) string {
return utils.B64UrlEncode(AesCBCEncrypt(false, b, key))
}
// AesCBCEnPKCS7B64 加密, Pkcs7Padding
func AesCBCEnPKCS7B64(b, key []byte) string {
return utils.B64UrlEncode(AesCBCEncrypt(true, b, key))
}
// AesCBCDeStringB64 解密, ZerosPadding
func AesCBCDeStringB64(s string, key []byte) string {
return utils.B2S(AesCBCDeB64(s, key))
}
// AesCBCDePKCS7StringB64 解密, Pkcs7Padding
func AesCBCDePKCS7StringB64(s string, key []byte) string {
return utils.B2S(AesCBCDePKCS7B64(s, key))
}
// AesCBCDeB64 解密, ZerosPadding
func AesCBCDeB64(s string, key []byte) []byte {
return AesCBCDecrypt(false, utils.B64UrlDecode(s), key)
}
// AesCBCDePKCS7B64 解密, Pkcs7Padding
func AesCBCDePKCS7B64(s string, key []byte) []byte {
return AesCBCDecrypt(true, utils.B64UrlDecode(s), key)
}
// AesCBCEncrypt AES-CBC 加密
func AesCBCEncrypt(asPKCS7 bool, plaintext, key []byte, ivs ...[]byte) (ciphertext []byte) {
ciphertext, _ = AesCBCEncryptE(asPKCS7, plaintext, key, ivs...)
return
}
// AesCBCDecrypt AES-CBC 解密
func AesCBCDecrypt(asPKCS7 bool, ciphertext, key []byte, ivs ...[]byte) (plaintext []byte) {
plaintext, _ = AesCBCDecryptE(asPKCS7, ciphertext, key, ivs...)
return
}
// AesCBCEncryptE AES-CBC 加密, 密码分组链接模式 (Cipher Block Chaining (CBC))
// key 长度分别是 16 (AES-128), 24 (AES-192?), 32 (AES-256?)
// asPKCS7: false (ZerosPadding), true (Pkcs7Padding)
func AesCBCEncryptE(asPKCS7 bool, plaintext, key []byte, ivs ...[]byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
defer func() {
if r := recover(); r != nil {
return
}
}()
// const BlockSize = 16
bSize := block.BlockSize()
plaintext = Padding(plaintext, bSize, asPKCS7)
// 向量无效时自动为 key[:blockSize]
var iv []byte
if len(ivs) > 0 && len(ivs[0]) == bSize {
iv = ivs[0]
} else {
iv = key[:bSize]
}
ciphertext := make([]byte, len(plaintext))
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext, plaintext)
return ciphertext, nil
}
// AesCBCDecryptE AES-CBC 解密, 密码分组链接模式 (Cipher Block Chaining (CBC))
func AesCBCDecryptE(asPKCS7 bool, ciphertext, key []byte, ivs ...[]byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
defer func() {
if r := recover(); r != nil {
return
}
}()
bSize := block.BlockSize()
// 向量无效时自动为 key[:blockSize]
var iv []byte
if len(ivs) > 0 && len(ivs[0]) == bSize {
iv = ivs[0]
} else {
iv = key[:bSize]
}
plaintext := make([]byte, len(ciphertext))
mode := cipher.NewCBCDecrypter(block, iv)
mode.CryptBlocks(plaintext, ciphertext)
plaintext = UnPadding(plaintext, asPKCS7)
return plaintext, nil
}
// Padding 填充
func Padding(b []byte, bSize int, pkcs7 bool) []byte {
if pkcs7 {
n := bSize - len(b)%bSize
pad := bytes.Repeat([]byte{byte(n)}, n)
return append(b, pad...)
}
n := bSize - len(b)%bSize
if n == 0 {
return b
} else {
return append(b, bytes.Repeat([]byte{byte(0)}, n)...)
}
}
// UnPadding 去除填充
func UnPadding(b []byte, pkcs7 bool) []byte {
if pkcs7 {
l := len(b)
n := int(b[l-1])
return b[:(l - n)]
}
for i := len(b) - 1; ; i-- {
if b[i] != 0 {
return b[:i+1]
}
}
}