Skip to content

Commit 75e86e9

Browse files
destinyoooodk-lockdown
authored andcommitted
feat: support selection of encryption and decryption methods, add gm sm4 crypto type
1 parent 35fc701 commit 75e86e9

6 files changed

Lines changed: 284 additions & 10 deletions

File tree

docker/conf/config_sdb.yaml

Lines changed: 1 addition & 0 deletions
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: aesgcm

go.mod

Lines changed: 1 addition & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 10 additions & 9 deletions
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 misc.CryptoType
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

Lines changed: 187 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,112 @@ import (
2121
"crypto/aes"
2222
"crypto/cipher"
2323
"crypto/rand"
24+
"fmt"
25+
"github.com/pkg/errors"
26+
"github.com/tjfoc/gmsm/sm4"
2427
"io"
28+
)
2529

26-
"github.com/pkg/errors"
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
2742
)
2843

44+
func (c *CryptoType) UnmarshalText(text []byte) error {
45+
if c == nil {
46+
return errors.New("can't unmarshal a nil *CryptoType")
47+
}
48+
if !c.unmarshalText(bytes.ToLower(text)) {
49+
return fmt.Errorf("unrecognized protocol type: %q", text)
50+
}
51+
return nil
52+
}
53+
54+
func (c *CryptoType) unmarshalText(text []byte) bool {
55+
switch string(text) {
56+
case "aesgcm":
57+
*c = CryptoAESGCM
58+
case "aescbc":
59+
*c = CryptoAESCBC
60+
case "aesecb":
61+
*c = CryptoAESECB
62+
case "aescfb":
63+
*c = CryptoAESCFB
64+
case "sm4gcm":
65+
*c = CryptoSM4GCM
66+
case "sm4ecb":
67+
*c = CryptoSM4ECB
68+
case "sm4cbc":
69+
*c = CryptoSM4CBC
70+
case "sm4cfb":
71+
*c = CryptoSM4CFB
72+
case "sm4ofb":
73+
*c = CryptoSM4OFB
74+
default:
75+
return false
76+
}
77+
return true
78+
}
79+
80+
func CryptoEncrypt(data []byte, key []byte, iv []byte, cryptoType CryptoType) ([]byte, error) {
81+
switch cryptoType {
82+
case CryptoAESGCM:
83+
return AesEncryptGCM(data, key, iv)
84+
case CryptoAESCBC:
85+
return AesEncryptCBC(data, key, iv)
86+
case CryptoAESECB:
87+
return AesEncryptECB(data, key)
88+
case CryptoAESCFB:
89+
return AesEncryptCFB(data, key)
90+
case CryptoSM4GCM:
91+
return Sm4EncryptGCM(data, key, iv)
92+
case CryptoSM4ECB:
93+
return Sm4EncryptECB(data, key)
94+
case CryptoSM4CBC:
95+
return Sm4EncryptCBC(data, key, iv)
96+
case CryptoSM4CFB:
97+
return Sm4EncryptCFB(data, key, iv)
98+
case CryptoSM4OFB:
99+
return Sm4EncryptOFB(data, key, iv)
100+
default:
101+
return AesEncryptGCM(data, key, iv)
102+
}
103+
}
104+
105+
func CryptoDecrypt(encrypted []byte, key []byte, iv []byte, cryptoType CryptoType) ([]byte, error) {
106+
switch cryptoType {
107+
case CryptoAESGCM:
108+
return AesDecryptGCM(encrypted, key, iv)
109+
case CryptoAESCBC:
110+
return AesDecryptCBC(encrypted, key, iv)
111+
case CryptoAESECB:
112+
return AesDecryptECB(encrypted, key)
113+
case CryptoAESCFB:
114+
return AesDecryptCFB(encrypted, key)
115+
case CryptoSM4GCM:
116+
return Sm4DecryptGCM(encrypted, key, iv)
117+
case CryptoSM4ECB:
118+
return Sm4DecryptECB(encrypted, key)
119+
case CryptoSM4CBC:
120+
return Sm4DecryptCBC(encrypted, key, iv)
121+
case CryptoSM4CFB:
122+
return Sm4DecryptCFB(encrypted, key, iv)
123+
case CryptoSM4OFB:
124+
return Sm4DecryptOFB(encrypted, key, iv)
125+
default:
126+
return AesDecryptGCM(encrypted, key, iv)
127+
}
128+
}
129+
29130
func AesEncryptGCM(origData []byte, key []byte, iv []byte) (encrypted []byte, err error) {
30131
var block cipher.Block
31132
block, err = aes.NewCipher(key)
@@ -178,3 +279,88 @@ func AesDecryptCFB(encrypted []byte, key []byte) (decrypted []byte, err error) {
178279
stream.XORKeyStream(encrypted, encrypted)
179280
return encrypted, err
180281
}
282+
283+
func Sm4EncryptGCM(origData, key []byte, iv []byte) (encrypted []byte, err error) {
284+
// Sm4GCM /**
285+
// key: 对称加密密钥
286+
// IV: IV向量
287+
// in:
288+
// A: 附加的可鉴别数据(ADD)
289+
// mode: true - 加密; false - 解密验证
290+
//
291+
// return: 密文C, 鉴别标签T, 错误
292+
encrypted, _, err = sm4.Sm4GCM(key, iv, origData, []byte{}, true)
293+
if err != nil {
294+
return nil, err
295+
}
296+
return encrypted, nil
297+
}
298+
299+
func Sm4DecryptGCM(encrypted, key []byte, iv []byte) (decrypted []byte, err error) {
300+
decrypted, _, err = sm4.Sm4GCM(key, iv, encrypted, []byte{}, true)
301+
if err != nil {
302+
return nil, err
303+
}
304+
return decrypted, nil
305+
}
306+
307+
func Sm4EncryptECB(origData, key []byte) (encrypted []byte, err error) {
308+
return sm4.Sm4Ecb(key, origData, true)
309+
}
310+
311+
func Sm4DecryptECB(encrypted, key []byte) (decrypted []byte, err error) {
312+
return sm4.Sm4Ecb(key, encrypted, false)
313+
}
314+
315+
func Sm4EncryptCBC(origData, key, iv []byte) (encrypted []byte, err error) {
316+
if err = sm4.SetIV(EnsureByteArrayLength16(iv)); err != nil {
317+
return nil, err
318+
}
319+
return sm4.Sm4Cbc(key, origData, true)
320+
}
321+
322+
func Sm4DecryptCBC(encrypted, key, iv []byte) (decrypted []byte, err error) {
323+
if err = sm4.SetIV(EnsureByteArrayLength16(iv)); err != nil {
324+
return nil, err
325+
}
326+
return sm4.Sm4Cbc(key, encrypted, false)
327+
}
328+
329+
func Sm4EncryptCFB(origData, key, iv []byte) (encrypted []byte, err error) {
330+
if err = sm4.SetIV(EnsureByteArrayLength16(iv)); err != nil {
331+
return nil, err
332+
}
333+
return sm4.Sm4CFB(key, origData, true)
334+
}
335+
336+
func Sm4DecryptCFB(encrypted, key, iv []byte) (decrypted []byte, err error) {
337+
if err = sm4.SetIV(EnsureByteArrayLength16(iv)); err != nil {
338+
return nil, err
339+
}
340+
return sm4.Sm4CFB(key, encrypted, false)
341+
}
342+
343+
func Sm4EncryptOFB(origData, key, iv []byte) (encrypted []byte, err error) {
344+
if err = sm4.SetIV(EnsureByteArrayLength16(iv)); err != nil {
345+
return nil, err
346+
}
347+
return sm4.Sm4OFB(key, origData, true)
348+
}
349+
350+
func Sm4DecryptOFB(encrypted, key, iv []byte) (decrypted []byte, err error) {
351+
if err = sm4.SetIV(EnsureByteArrayLength16(iv)); err != nil {
352+
return nil, err
353+
}
354+
return sm4.Sm4OFB(key, encrypted, false)
355+
}
356+
357+
func EnsureByteArrayLength16(input []byte) []byte {
358+
if len(input) == 16 {
359+
return input
360+
}
361+
repeated := append(input, input...)
362+
for len(repeated) < 16 {
363+
repeated = append(repeated, input...)
364+
}
365+
return repeated[:16]
366+
}

pkg/misc/crypto_test.go

Lines changed: 81 additions & 0 deletions
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)