Skip to content

Commit 8d16d44

Browse files
committed
feat: support selection of encryption and decryption methods, add gm sm4 crypto type
1 parent 35fc701 commit 8d16d44

File tree

6 files changed

+236
-9
lines changed

6 files changed

+236
-9
lines changed

docker/conf/config_sdb.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,4 @@ app_config:
7171
- table: departments
7272
columns: [ "dept_name" ]
7373
aeskey: 123456789abcdefg
74+
cryptoType: 4

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ require (
3232
github.com/spf13/cobra v1.1.1
3333
github.com/stretchr/testify v1.7.1
3434
github.com/testcontainers/testcontainers-go v0.13.0
35+
github.com/tjfoc/gmsm v1.4.1
3536
github.com/uber-go/atomic v1.4.0
3637
github.com/valyala/fasthttp v1.34.0
3738
go.etcd.io/etcd/api/v3 v3.5.0-alpha.0

go.sum

+4
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,8 @@ github.com/tikv/client-go/v2 v2.0.0-alpha.0.20210831090540-391fcd842dc8/go.mod h
12371237
github.com/tikv/pd v1.1.0-beta.0.20210323121136-78679e5e209d/go.mod h1:Jw9KG11C/23Rr7DW4XWQ7H5xOgGZo6DFL1OKAF4+Igw=
12381238
github.com/tikv/pd v1.1.0-beta.0.20210818112400-0c5667766690 h1:qGn7fDqj7IZ5dozy7QVkoj+0bama92ruVGHqoCBg7W4=
12391239
github.com/tikv/pd v1.1.0-beta.0.20210818112400-0c5667766690/go.mod h1:rammPjeZgpvfrQRPkijcx8tlxF1XM5+m6kRXrkDzCAA=
1240+
github.com/tjfoc/gmsm v1.4.1 h1:aMe1GlZb+0bLjn+cKTPEvvn9oUEBlJitaZiiBwsbgho=
1241+
github.com/tjfoc/gmsm v1.4.1/go.mod h1:j4INPkHWMrhJb38G+J6W4Tw0AbuN8Thu3PbdVYhVcTE=
12401242
github.com/tklauser/go-sysconf v0.3.4/go.mod h1:Cl2c8ZRWfHD5IrfHo9VN+FX9kCFjIOyVklgXycLB6ek=
12411243
github.com/tklauser/numcpus v0.2.1/go.mod h1:9aU+wOc6WjUIZEwWMP62PL/41d65P+iks1gBkr4QyP8=
12421244
github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -1412,6 +1414,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh
14121414
golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
14131415
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
14141416
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
1417+
golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
14151418
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
14161419
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
14171420
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
@@ -1505,6 +1508,7 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
15051508
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
15061509
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
15071510
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
1511+
golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
15081512
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
15091513
golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
15101514
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=

pkg/filter/crypto/filter.go

+10-9
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,10 @@ type _filter struct {
6767
}
6868

6969
type ColumnCrypto struct {
70-
Table string
71-
Columns []string
72-
AesKey string
70+
Table string
71+
Columns []string
72+
AesKey string
73+
CryptoType int
7374
}
7475

7576
type columnIndex struct {
@@ -304,7 +305,7 @@ func encryptInsertValues(columns []*columnIndex, config *ColumnCrypto, valueList
304305
if param, ok := arg.(*driver.ValueExpr); ok {
305306
value := param.GetBytes()
306307
if len(value) != 0 {
307-
encoded, err := misc.AesEncryptGCM(value, []byte(config.AesKey), []byte(aesIV))
308+
encoded, err := misc.CryptoEncrypt(value, []byte(config.AesKey), []byte(aesIV), config.CryptoType)
308309
if err != nil {
309310
return errors.Wrapf(err, "Encryption of %s failed", column.Column)
310311
}
@@ -326,7 +327,7 @@ func encryptUpdateValues(updateStmt *ast.UpdateStmt, config *ColumnCrypto) error
326327
if param, ok := arg.(*driver.ValueExpr); ok {
327328
value := param.GetBytes()
328329
if len(value) != 0 {
329-
encoded, err := misc.AesEncryptGCM(value, []byte(config.AesKey), []byte(aesIV))
330+
encoded, err := misc.CryptoEncrypt(value, []byte(config.AesKey), []byte(aesIV), config.CryptoType)
330331
if err != nil {
331332
return errors.Wrapf(err, "Encryption of %s failed", column.Column)
332333
}
@@ -345,14 +346,14 @@ func encryptBindVars(columns []*columnIndex, config *ColumnCrypto, args *map[str
345346
parameterID := fmt.Sprintf("v%d", column.Index+1)
346347
param := (*args)[parameterID]
347348
if arg, ok := param.(string); ok {
348-
encoded, err := misc.AesEncryptGCM([]byte(arg), []byte(config.AesKey), []byte(aesIV))
349+
encoded, err := misc.CryptoEncrypt([]byte(arg), []byte(config.AesKey), []byte(aesIV), config.CryptoType)
349350
if err != nil {
350351
return errors.Errorf("Encryption of %s failed: %v", column.Column, err)
351352
}
352353
val := hex.EncodeToString(encoded)
353354
(*args)[parameterID] = val
354355
} else if arg, ok := param.([]byte); ok {
355-
encoded, err := misc.AesEncryptGCM(arg, []byte(config.AesKey), []byte(aesIV))
356+
encoded, err := misc.CryptoEncrypt(arg, []byte(config.AesKey), []byte(aesIV), config.CryptoType)
356357
if err != nil {
357358
return errors.Errorf("Encryption of %s failed: %v", column.Column, err)
358359
}
@@ -372,7 +373,7 @@ func decryptDecodedResult(decodedResult *mysql.Result, config *ColumnCrypto, col
372373
if protoValue != nil {
373374
if originalVal, ok := protoValue.Val.([]byte); ok {
374375
if n, err := hex.Decode(originalVal, originalVal); err == nil {
375-
if decodedVal, err := misc.AesDecryptGCM(originalVal[:n], []byte(config.AesKey), []byte(aesIV)); err == nil {
376+
if decodedVal, err := misc.CryptoDecrypt(originalVal[:n], []byte(config.AesKey), []byte(aesIV), config.CryptoType); err == nil {
376377
r.Values[column.Index].Val = decodedVal
377378
}
378379
}
@@ -385,7 +386,7 @@ func decryptDecodedResult(decodedResult *mysql.Result, config *ColumnCrypto, col
385386
if protoValue != nil {
386387
if originalVal, ok := protoValue.Val.([]byte); ok {
387388
if n, err := hex.Decode(originalVal, originalVal); err == nil {
388-
if decodedVal, err := misc.AesDecryptGCM(originalVal[:n], []byte(config.AesKey), []byte(aesIV)); err == nil {
389+
if decodedVal, err := misc.CryptoDecrypt(originalVal[:n], []byte(config.AesKey), []byte(aesIV), config.CryptoType); err == nil {
389390
r.Values[column.Index].Val = decodedVal
390391
}
391392
}

pkg/misc/crypto.go

+139
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,73 @@ import (
2424
"io"
2525

2626
"github.com/pkg/errors"
27+
"github.com/tjfoc/gmsm/sm4"
2728
)
2829

30+
type CryptoType int
31+
32+
const (
33+
CryptoAESGCM CryptoType = iota
34+
CryptoAESCBC
35+
CryptoAESECB
36+
CryptoAESCFB
37+
CryptoSM4GCM
38+
CryptoSM4ECB
39+
CryptoSM4CBC
40+
CryptoSM4CFB
41+
CryptoSM4OFB
42+
)
43+
44+
func CryptoEncrypt(data []byte, key []byte, iv []byte, cryptoType int) ([]byte, error) {
45+
switch CryptoType(cryptoType) {
46+
case CryptoAESGCM:
47+
return AesEncryptGCM(data, key, iv)
48+
case CryptoAESCBC:
49+
return AesEncryptCBC(data, key, iv)
50+
case CryptoAESECB:
51+
return AesEncryptECB(data, key)
52+
case CryptoAESCFB:
53+
return AesEncryptCFB(data, key)
54+
case CryptoSM4GCM:
55+
return Sm4EncryptGCM(data, key, iv)
56+
case CryptoSM4ECB:
57+
return Sm4EncryptECB(data, key)
58+
case CryptoSM4CBC:
59+
return Sm4EncryptCBC(data, key, iv)
60+
case CryptoSM4CFB:
61+
return Sm4EncryptCFB(data, key, iv)
62+
case CryptoSM4OFB:
63+
return Sm4EncryptOFB(data, key, iv)
64+
default:
65+
return AesEncryptGCM(data, key, iv)
66+
}
67+
}
68+
69+
func CryptoDecrypt(encrypted []byte, key []byte, iv []byte, cryptoType int) ([]byte, error) {
70+
switch CryptoType(cryptoType) {
71+
case CryptoAESGCM:
72+
return AesDecryptGCM(encrypted, key, iv)
73+
case CryptoAESCBC:
74+
return AesDecryptCBC(encrypted, key, iv)
75+
case CryptoAESECB:
76+
return AesDecryptECB(encrypted, key)
77+
case CryptoAESCFB:
78+
return AesDecryptCFB(encrypted, key)
79+
case CryptoSM4GCM:
80+
return Sm4DecryptGCM(encrypted, key, iv)
81+
case CryptoSM4ECB:
82+
return Sm4DecryptECB(encrypted, key)
83+
case CryptoSM4CBC:
84+
return Sm4DecryptCBC(encrypted, key, iv)
85+
case CryptoSM4CFB:
86+
return Sm4DecryptCFB(encrypted, key, iv)
87+
case CryptoSM4OFB:
88+
return Sm4DecryptOFB(encrypted, key, iv)
89+
default:
90+
return AesDecryptGCM(encrypted, key, iv)
91+
}
92+
}
93+
2994
func AesEncryptGCM(origData []byte, key []byte, iv []byte) (encrypted []byte, err error) {
3095
var block cipher.Block
3196
block, err = aes.NewCipher(key)
@@ -178,3 +243,77 @@ func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte, err error) {
178243
stream.XORKeyStream(encrypted, encrypted)
179244
return encrypted, err
180245
}
246+
247+
func Sm4EncryptGCM(origData, key []byte, iv []byte) (encrypted []byte, err error) {
248+
// Sm4GCM /**
249+
// key: 对称加密密钥
250+
// IV: IV向量
251+
// in:
252+
// A: 附加的可鉴别数据(ADD)
253+
// mode: true - 加密; false - 解密验证
254+
//
255+
// return: 密文C, 鉴别标签T, 错误
256+
encrypted, _, err = sm4.Sm4GCM(key, iv, origData, []byte{}, true)
257+
if err != nil {
258+
return nil, err
259+
}
260+
return encrypted, nil
261+
}
262+
263+
func Sm4DecryptGCM(encrypted, key []byte, iv []byte) (decrypted []byte, err error) {
264+
decrypted, _, err = sm4.Sm4GCM(key, iv, encrypted, []byte{}, true)
265+
if err != nil {
266+
return nil, err
267+
}
268+
return decrypted, nil
269+
}
270+
271+
func Sm4EncryptECB(origData, key []byte) (encrypted []byte, err error) {
272+
return sm4.Sm4Ecb(key, origData, true)
273+
}
274+
275+
func Sm4DecryptECB(encrypted, key []byte) (decrypted []byte, err error) {
276+
return sm4.Sm4Ecb(key, encrypted, false)
277+
}
278+
279+
func Sm4EncryptCBC(origData, key, iv []byte) (encrypted []byte, err error) {
280+
if err = sm4.SetIV(iv); err != nil {
281+
return nil, err
282+
}
283+
return sm4.Sm4Cbc(key, origData, true)
284+
}
285+
286+
func Sm4DecryptCBC(encrypted, key, iv []byte) (decrypted []byte, err error) {
287+
if err = sm4.SetIV(iv); err != nil {
288+
return nil, err
289+
}
290+
return sm4.Sm4Cbc(key, encrypted, false)
291+
}
292+
293+
func Sm4EncryptCFB(origData, key, iv []byte) (encrypted []byte, err error) {
294+
if err = sm4.SetIV(iv); err != nil {
295+
return nil, err
296+
}
297+
return sm4.Sm4CFB(key, origData, true)
298+
}
299+
300+
func Sm4DecryptCFB(encrypted, key, iv []byte) (decrypted []byte, err error) {
301+
if err = sm4.SetIV(iv); err != nil {
302+
return nil, err
303+
}
304+
return sm4.Sm4CFB(key, encrypted, false)
305+
}
306+
307+
func Sm4EncryptOFB(origData, key, iv []byte) (encrypted []byte, err error) {
308+
if err = sm4.SetIV(iv); err != nil {
309+
return nil, err
310+
}
311+
return sm4.Sm4OFB(key, origData, true)
312+
}
313+
314+
func Sm4DecryptOFB(encrypted, key, iv []byte) (decrypted []byte, err error) {
315+
if err = sm4.SetIV(iv); err != nil {
316+
return nil, err
317+
}
318+
return sm4.Sm4OFB(key, encrypted, false)
319+
}

pkg/misc/crypto_test.go

+81
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,84 @@ func TestAesDecryptCFB(t *testing.T) {
8686
assert.Nil(t, err)
8787
assert.Equal(t, []byte("exampleplaintext"), decrypted)
8888
}
89+
90+
func TestSm4EncryptGCM(t *testing.T) {
91+
key, _ := hex.DecodeString("31323334353637383961626364656667")
92+
plaintext := []byte("sunset4")
93+
encrypted, err := Sm4EncryptGCM(plaintext, key, []byte("greatdbpack!"))
94+
assert.Nil(t, err)
95+
t.Logf("%x", encrypted)
96+
}
97+
98+
func TestSm4DecryptGCM(t *testing.T) {
99+
key, _ := hex.DecodeString("31323334353637383961626364656667")
100+
encrypted, _ := hex.DecodeString("4b3dd6cb3e0145")
101+
decrypted, err := Sm4DecryptGCM(encrypted, key, []byte("greatdbpack!"))
102+
assert.Nil(t, err)
103+
t.Logf("%s", decrypted)
104+
assert.Equal(t, []byte("sunset4"), decrypted)
105+
}
106+
107+
func TestSm4EncryptECB(t *testing.T) {
108+
key, _ := hex.DecodeString("6368616e676520746869732070617373")
109+
plaintext := []byte("exampleplaintext")
110+
encrypted, err := Sm4EncryptECB(plaintext, key)
111+
assert.Nil(t, err)
112+
t.Logf("%x", encrypted)
113+
}
114+
115+
func TestSm4DecryptECB(t *testing.T) {
116+
key, _ := hex.DecodeString("6368616e676520746869732070617373")
117+
encrypted, _ := hex.DecodeString("1cadd74166afbe5f4bdaf6ebb49d4c46ce96714d2c0839338f995f4854c61b58")
118+
decrypted, err := Sm4DecryptECB(encrypted, key)
119+
assert.Nil(t, err)
120+
assert.Equal(t, []byte("exampleplaintext"), decrypted)
121+
}
122+
123+
func TestSm4EncryptCBC(t *testing.T) {
124+
key, _ := hex.DecodeString("6368616e676520746869732070617373")
125+
plaintext := []byte("exampleplaintext")
126+
encrypted, err := Sm4EncryptCBC(plaintext, key, []byte("impressivedbpack"))
127+
assert.Nil(t, err)
128+
t.Logf("%x", encrypted)
129+
}
130+
131+
func TestSm4DecryptCBC(t *testing.T) {
132+
key, _ := hex.DecodeString("6368616e676520746869732070617373")
133+
encrypted, _ := hex.DecodeString("2e88063cb32a13ce8fbfb60512c23d78d257734049682849d7c82a19f00e131a")
134+
decrypted, err := Sm4DecryptCBC(encrypted, key, []byte("impressivedbpack"))
135+
assert.Nil(t, err)
136+
assert.Equal(t, []byte("exampleplaintext"), decrypted)
137+
}
138+
139+
func TestSm4EncryptCFB(t *testing.T) {
140+
key, _ := hex.DecodeString("6368616e676520746869732070617373")
141+
plaintext := []byte("exampleplaintext")
142+
encrypted, err := Sm4EncryptCFB(plaintext, key, []byte("impressivedbpack"))
143+
assert.Nil(t, err)
144+
t.Logf("%x", encrypted)
145+
}
146+
147+
func TestSm4DecryptCFB(t *testing.T) {
148+
key, _ := hex.DecodeString("6368616e676520746869732070617373")
149+
encrypted, _ := hex.DecodeString("5ce63f4fac3744073aa91ac44bdc4ab44a19895a9fcb106947eae2cecfd99e62")
150+
decrypted, err := Sm4DecryptCFB(encrypted, key, []byte("impressivedbpack"))
151+
assert.Nil(t, err)
152+
assert.Equal(t, []byte("exampleplaintext"), decrypted)
153+
}
154+
155+
func TestSm4EncryptOFB(t *testing.T) {
156+
key, _ := hex.DecodeString("6368616e676520746869732070617373")
157+
plaintext := []byte("exampleplaintext")
158+
encrypted, err := Sm4EncryptOFB(plaintext, key, []byte("impressivedbpack"))
159+
assert.Nil(t, err)
160+
t.Logf("%x", encrypted)
161+
}
162+
163+
func TestSm4DecryptOFB(t *testing.T) {
164+
key, _ := hex.DecodeString("6368616e676520746869732070617373")
165+
encrypted, _ := hex.DecodeString("5ce63f4fac3744073aa91ac44bdc4ab4f83abab6ff8e4fd91da0740e339f9b2d")
166+
decrypted, err := Sm4DecryptOFB(encrypted, key, []byte("impressivedbpack"))
167+
assert.Nil(t, err)
168+
assert.Equal(t, []byte("exampleplaintext"), decrypted)
169+
}

0 commit comments

Comments
 (0)