From b1b66b762e4a24868299bc7103ba0b3d90535068 Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Wed, 5 Sep 2018 23:26:50 +0800 Subject: [PATCH 01/13] Add two buildin function ( decode and encode) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add two buildin function ( decode and encode): 1) add crypt.go to util/encrypt 2) modify buildin_encryption.go --- expression/builtin_encryption.go | 74 +++++++++++++- expression/builtin_encryption_test.go | 39 +++++++ util/encrypt/crypt.go | 141 ++++++++++++++++++++++++++ util/encrypt/crypt_test.go | 82 +++++++++++++++ 4 files changed, 334 insertions(+), 2 deletions(-) create mode 100644 util/encrypt/crypt.go create mode 100644 util/encrypt/crypt_test.go diff --git a/expression/builtin_encryption.go b/expression/builtin_encryption.go index 0430499bbc09d..358857e25022f 100644 --- a/expression/builtin_encryption.go +++ b/expression/builtin_encryption.go @@ -174,7 +174,42 @@ type decodeFunctionClass struct { } func (c *decodeFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) { - return nil, errFunctionNotExists.GenByArgs("FUNCTION", "DECODE") + if err := c.verifyArgs(args); err != nil { + return nil, errors.Trace(err) + } + + bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETString, types.ETString) + + bf.tp.Flen = args[0].GetType().Flen + sig := &builtinDecodeSig{bf} + return sig, nil +} + +type builtinDecodeSig struct { + baseBuiltinFunc +} + +func (b *builtinDecodeSig) Clone() builtinFunc { + newSig := &builtinDecodeSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + return newSig +} + +// evalString evals DECODE(str, password_str). +// See https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_decode +func (b *builtinDecodeSig) evalString(row chunk.Row) (string, bool, error) { + dataStr, isNull, err := b.args[0].EvalString(b.ctx, row) + if isNull || err != nil { + return "", true, errors.Trace(err) + } + + passwordStr, isNull, err := b.args[1].EvalString(b.ctx, row) + if isNull || err != nil { + return "", true, errors.Trace(err) + } + + decodeStr, _ := encrypt.SQLDecode(dataStr, passwordStr) + return decodeStr, false, nil } type desDecryptFunctionClass struct { @@ -198,7 +233,42 @@ type encodeFunctionClass struct { } func (c *encodeFunctionClass) getFunction(ctx sessionctx.Context, args []Expression) (builtinFunc, error) { - return nil, errFunctionNotExists.GenByArgs("FUNCTION", "ENCODE") + if err := c.verifyArgs(args); err != nil { + return nil, errors.Trace(err) + } + + bf := newBaseBuiltinFuncWithTp(ctx, args, types.ETString, types.ETString, types.ETString) + + bf.tp.Flen = args[0].GetType().Flen + sig := &builtinEncodeSig{bf} + return sig, nil +} + +type builtinEncodeSig struct { + baseBuiltinFunc +} + +func (b *builtinEncodeSig) Clone() builtinFunc { + newSig := &builtinEncodeSig{} + newSig.cloneFrom(&b.baseBuiltinFunc) + return newSig +} + +// evalString evals ENCODE(crypt_str, password_str). +// See https://dev.mysql.com/doc/refman/5.7/en/encryption-functions.html#function_encode +func (b *builtinEncodeSig) evalString(row chunk.Row) (string, bool, error) { + decodeStr, isNull, err := b.args[0].EvalString(b.ctx, row) + if isNull || err != nil { + return "", true, errors.Trace(err) + } + + passwordStr, isNull, err := b.args[1].EvalString(b.ctx, row) + if isNull || err != nil { + return "", true, errors.Trace(err) + } + + dataStr, _ := encrypt.SQLEncode(decodeStr, passwordStr) + return dataStr, false, nil } type encryptFunctionClass struct { diff --git a/expression/builtin_encryption_test.go b/expression/builtin_encryption_test.go index 5d80199f15778..175e1179a095c 100644 --- a/expression/builtin_encryption_test.go +++ b/expression/builtin_encryption_test.go @@ -26,6 +26,45 @@ import ( "github.com/pingcap/tidb/util/testleak" ) +var cryptTests = []struct { + origin interface{} + password interface{} + crypt interface{} +}{ + {"", "", ""}, + {"pingcap", "1234567890123456", "2C35B5A4ADF391"}, + {"pingcap", "asdfjasfwefjfjkj", "351CC412605905"}, + {"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221"}, + {"pingcap#%$%^", "*^%YTu1234567", "8634B9C55FF55E5B6328F449"}, + {"pingcap", "", "4A77B524BD2C5C"}, +} + +func (s *testEvaluatorSuite) TestSQLDecode(c *C) { + defer testleak.AfterTest(c)() + fc := funcs[ast.Decode] + for _, tt := range cryptTests { + str := types.NewDatum(tt.origin) + password := types.NewDatum(tt.password) + f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Datum{str, password})) + crypt, err := evalBuiltinFunc(f, chunk.Row{}) + c.Assert(err, IsNil) + c.Assert(toHex(crypt), DeepEquals, types.NewDatum(tt.crypt)) + } +} + +func (s *testEvaluatorSuite) TestSQLEncode(c *C) { + defer testleak.AfterTest(c)() + fc := funcs[ast.Encode] + for _, test := range aesTests { + cryptStr := fromHex(test.crypt) + password := types.NewDatum(test.password) + f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Datum{cryptStr, password})) + str, err := evalBuiltinFunc(f, chunk.Row{}) + c.Assert(err, IsNil) + c.Assert(str, DeepEquals, types.NewDatum(test.origin)) + } +} + var aesTests = []struct { origin interface{} key interface{} diff --git a/util/encrypt/crypt.go b/util/encrypt/crypt.go new file mode 100644 index 0000000000000..22fa1a37dbf28 --- /dev/null +++ b/util/encrypt/crypt.go @@ -0,0 +1,141 @@ +// Copyright 2017 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package encrypt + +import ( + "fmt" +) + +type randStruct struct { + seed1 uint32 + seed2 uint32 + maxValue uint32 + maxValueDbl float64 +} + +func (rs *randStruct) randomInit(password []byte, length int) { + // hash password + var nr,add,nr2,tmp uint32 + nr = 1345345333 + add=7 + nr2=0x12345671 + + for i:=0; i< length; i++ { + pswChar := password[i] + if pswChar == ' ' || pswChar == '\t' { + continue; + } + tmp = uint32(pswChar) + nr^= (((nr & 63)+add)*tmp)+ (nr << 8) + nr2+=(nr2 << 8) ^ nr + add+=tmp + } + + seed1 := nr & ((uint32(1) << 31) -uint32(1)) + seed2 := nr2 & ((uint32(1) << 31) -uint32(1)) + + fmt.Println(seed1) + fmt.Println(seed2) + + // init rand struct + rs.maxValue = 0x3FFFFFFF + rs.maxValueDbl = float64(rs.maxValue) + rs.seed1 = seed1 % rs.maxValue + rs.seed2 = seed2 % rs.maxValue +} + +func (rs *randStruct) myRand() float64 { + rs.seed1 = (rs.seed1*3 + rs.seed2) % rs.maxValue + rs.seed2 = (rs.seed1 + rs.seed2 + 33) % rs.maxValue + + return ((float64(rs.seed1))/ rs.maxValueDbl) +} + +type SqlCrypt struct { + rand randStruct + orgRand randStruct + + decodeBuff [256]byte + encodeBuff [256]byte + shift uint32 +} + +func (sc *SqlCrypt) init(password []byte, length int) { + sc.rand.randomInit(password, length) + + for i := 0; i <= 255; i++ { + sc.decodeBuff[i] = byte(i) + } + + for i := 0; i <= 255; i++ { + idx := uint32(sc.rand.myRand() * 255.0) + a := sc.decodeBuff[idx] + sc.decodeBuff[idx] = sc.decodeBuff[i] + sc.decodeBuff[i] = a + } + + for i := 0; i <= 255; i++ { + sc.encodeBuff[sc.decodeBuff[i]] = byte(i) + } + + sc.orgRand = sc.rand + sc.shift = 0 +} + +func (sc *SqlCrypt) reinit() { + sc.shift = 0 + sc.rand = sc.orgRand +} + +func (sc *SqlCrypt) encode(str []byte, length int) { + for i := 0; i < length; i++ { + sc.shift ^= uint32(sc.rand.myRand() * 255.0) + idx := uint32(str[i]) + str[i] = sc.encodeBuff[idx] ^ byte(sc.shift) + sc.shift ^= idx + } +} + +func (sc *SqlCrypt) decode(str []byte, length int) { + for i := 0; i < length; i++ { + sc.shift ^= uint32(sc.rand.myRand() * 255.0) + idx := uint32(str[i] ^ byte(sc.shift)) + str[i] = sc.decodeBuff[idx] + sc.shift ^= uint32(str[i]) + } +} + +func SQLDecode(str string, password string) (string,error) { + var sqlCrypt SqlCrypt + + strByte := []byte(str) + passwdByte := []byte(password) + + sqlCrypt.init(passwdByte,len(passwdByte)) + sqlCrypt.decode(strByte,len(strByte)) + + return string(strByte),nil +} + +func SQLEncode(cryptStr string, password string) (string, error) { + var sqlCrypt SqlCrypt + + cryptStrByte := []byte(cryptStr) + passwdByte := []byte(password) + + sqlCrypt.init(passwdByte,len(passwdByte)) + sqlCrypt.encode(cryptStrByte,len(cryptStrByte)) + + return string(cryptStrByte),nil +} diff --git a/util/encrypt/crypt_test.go b/util/encrypt/crypt_test.go new file mode 100644 index 0000000000000..4d2418a7c3682 --- /dev/null +++ b/util/encrypt/crypt_test.go @@ -0,0 +1,82 @@ +// Copyright 2017 PingCAP, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// See the License for the specific language governing permissions and +// limitations under the License. + +package encrypt + +import ( + "crypto/aes" + "encoding/hex" + "strings" + "testing" + + . "github.com/pingcap/check" + "github.com/pingcap/tidb/util/testleak" +) + + +func (s *testEncryptSuite) TestSQLDecode(c *C) { + defer testleak.AfterTest(c)() + tests := []struct { + str string + passwd string + expect string + isError bool + }{ + {"", "", "", false}, + {"pingcap", "1234567890123456", "2C35B5A4ADF391", false}, + {"pingcap", "asdfjasfwefjfjkj", "351CC412605905", false}, + {"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221", false}, + {"pingcap#%$%^", "*^%YTu1234567", "8634B9C55FF55E5B6328F449", false}, + {"pingcap", "", "4A77B524BD2C5C", false}, + } + + for _, t := range tests { + crypted, err := SQLDecode(t.str, t.passwd) + if t.isError { + c.Assert(err, NotNil, Commentf("%v", t)) + continue + } + c.Assert(err, IsNil, Commentf("%v", t)) + result := toHex(crypted) + c.Assert(result, Equals, t.expect, Commentf("%v", t)) + } +} + +func (s *testEncryptSuite) TestSQLEncode(c *C) { + defer testleak.AfterTest(c)() + tests := []struct { + str string + passwd string + expect string + isError bool + }{ + {"", "", "", false}, + {"pingcap", "1234567890123456", "pingcap", false}, + {"pingcap", "asdfjasfwefjfjkj", "pingcap", false}, + {"pingcap123", "123456789012345678901234", "pingcap123", false}, + {"pingcap#%$%^", "*^%YTu1234567", "pingcap#%$%^", false}, + {"pingcap", "", "pingcap", false}, + } + + for _, t := range tests { + crypted, err := SQLDecode(t.str, t.passwd) + uncrypte, err := SQLEncode(crypte, t.passwd) + + if t.isError { + c.Assert(err, NotNil, Commentf("%v", t)) + continue + } + c.Assert(err, IsNil, Commentf("%v", t)) + c.Assert(ncrypte, Equals, t.expect, Commentf("%v", t)) + } +} From 6406474184233d912e72a0544e0eb7b175c2fbc4 Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Wed, 5 Sep 2018 23:53:45 +0800 Subject: [PATCH 02/13] Add two buildin function ( decode and encode) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mysql> select decode("pingancap","pass1234"); +--------------------------------+ | decode("pingancap","pass1234") | +--------------------------------+ | .�[P�n��� | +--------------------------------+ 1 row in set (0.32 sec) mysql> select encode(decode("pingancap","pass1234"),"pass1234"); +---------------------------------------------------+ | encode(decode("pingancap","pass1234"),"pass1234") | +---------------------------------------------------+ | pingancap | +---------------------------------------------------+ 1 row in set (0.00 sec) mysql> --- util/encrypt/crypt_test.go | 56 +++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 31 deletions(-) diff --git a/util/encrypt/crypt_test.go b/util/encrypt/crypt_test.go index 4d2418a7c3682..d328e3d09441a 100644 --- a/util/encrypt/crypt_test.go +++ b/util/encrypt/crypt_test.go @@ -14,16 +14,10 @@ package encrypt import ( - "crypto/aes" - "encoding/hex" - "strings" - "testing" - . "github.com/pingcap/check" "github.com/pingcap/tidb/util/testleak" ) - func (s *testEncryptSuite) TestSQLDecode(c *C) { defer testleak.AfterTest(c)() tests := []struct { @@ -35,7 +29,7 @@ func (s *testEncryptSuite) TestSQLDecode(c *C) { {"", "", "", false}, {"pingcap", "1234567890123456", "2C35B5A4ADF391", false}, {"pingcap", "asdfjasfwefjfjkj", "351CC412605905", false}, - {"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221", false}, + {"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221", false}, {"pingcap#%$%^", "*^%YTu1234567", "8634B9C55FF55E5B6328F449", false}, {"pingcap", "", "4A77B524BD2C5C", false}, } @@ -53,30 +47,30 @@ func (s *testEncryptSuite) TestSQLDecode(c *C) { } func (s *testEncryptSuite) TestSQLEncode(c *C) { - defer testleak.AfterTest(c)() - tests := []struct { - str string - passwd string - expect string - isError bool - }{ - {"", "", "", false}, - {"pingcap", "1234567890123456", "pingcap", false}, - {"pingcap", "asdfjasfwefjfjkj", "pingcap", false}, - {"pingcap123", "123456789012345678901234", "pingcap123", false}, - {"pingcap#%$%^", "*^%YTu1234567", "pingcap#%$%^", false}, - {"pingcap", "", "pingcap", false}, - } + defer testleak.AfterTest(c)() + tests := []struct { + str string + passwd string + expect string + isError bool + }{ + {"", "", "", false}, + {"pingcap", "1234567890123456", "pingcap", false}, + {"pingcap", "asdfjasfwefjfjkj", "pingcap", false}, + {"pingcap123", "123456789012345678901234", "pingcap123", false}, + {"pingcap#%$%^", "*^%YTu1234567", "pingcap#%$%^", false}, + {"pingcap", "", "pingcap", false}, + } - for _, t := range tests { - crypted, err := SQLDecode(t.str, t.passwd) - uncrypte, err := SQLEncode(crypte, t.passwd) + for _, t := range tests { + crypted, err := SQLDecode(t.str, t.passwd) + uncrypte, err := SQLEncode(crypted, t.passwd) - if t.isError { - c.Assert(err, NotNil, Commentf("%v", t)) - continue - } - c.Assert(err, IsNil, Commentf("%v", t)) - c.Assert(ncrypte, Equals, t.expect, Commentf("%v", t)) - } + if t.isError { + c.Assert(err, NotNil, Commentf("%v", t)) + continue + } + c.Assert(err, IsNil, Commentf("%v", t)) + c.Assert(uncrypte, Equals, t.expect, Commentf("%v", t)) + } } From be1cdec35ee242c4df996be8496a7ab06f130c47 Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Wed, 5 Sep 2018 23:59:43 +0800 Subject: [PATCH 03/13] add two buildin function ( decode and encode) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mysql> select decode("pingancap","pass1234"); +--------------------------------+ | decode("pingancap","pass1234") | +--------------------------------+ | .�[P�n��� | +--------------------------------+ 1 row in set (0.32 sec) mysql> select encode(decode("pingancap","pass1234"),"pass1234"); +---------------------------------------------------+ | encode(decode("pingancap","pass1234"),"pass1234") | +---------------------------------------------------+ | pingancap | +---------------------------------------------------+ 1 row in set (0.00 sec) mysql> --- util/encrypt/crypt_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/encrypt/crypt_test.go b/util/encrypt/crypt_test.go index d328e3d09441a..4064af3f62599 100644 --- a/util/encrypt/crypt_test.go +++ b/util/encrypt/crypt_test.go @@ -41,7 +41,7 @@ func (s *testEncryptSuite) TestSQLDecode(c *C) { continue } c.Assert(err, IsNil, Commentf("%v", t)) - result := toHex(crypted) + result := toHex([]type(crypted)) c.Assert(result, Equals, t.expect, Commentf("%v", t)) } } From 4e4459a3df6ebe3eeff2955941f23a1b7ddbad7e Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Thu, 6 Sep 2018 20:35:17 +0800 Subject: [PATCH 04/13] fix ci --- expression/builtin_encryption.go | 8 ++--- expression/builtin_encryption_test.go | 2 +- util/encrypt/crypt.go | 50 +++++++++++++-------------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/expression/builtin_encryption.go b/expression/builtin_encryption.go index 358857e25022f..ada2da3e60862 100644 --- a/expression/builtin_encryption.go +++ b/expression/builtin_encryption.go @@ -208,8 +208,8 @@ func (b *builtinDecodeSig) evalString(row chunk.Row) (string, bool, error) { return "", true, errors.Trace(err) } - decodeStr, _ := encrypt.SQLDecode(dataStr, passwordStr) - return decodeStr, false, nil + decodeStr, err := encrypt.SQLDecode(dataStr, passwordStr) + return decodeStr, err, nil } type desDecryptFunctionClass struct { @@ -267,8 +267,8 @@ func (b *builtinEncodeSig) evalString(row chunk.Row) (string, bool, error) { return "", true, errors.Trace(err) } - dataStr, _ := encrypt.SQLEncode(decodeStr, passwordStr) - return dataStr, false, nil + dataStr, err := encrypt.SQLEncode(decodeStr, passwordStr) + return dataStr, err, nil } type encryptFunctionClass struct { diff --git a/expression/builtin_encryption_test.go b/expression/builtin_encryption_test.go index 175e1179a095c..b6431888dea19 100644 --- a/expression/builtin_encryption_test.go +++ b/expression/builtin_encryption_test.go @@ -55,7 +55,7 @@ func (s *testEvaluatorSuite) TestSQLDecode(c *C) { func (s *testEvaluatorSuite) TestSQLEncode(c *C) { defer testleak.AfterTest(c)() fc := funcs[ast.Encode] - for _, test := range aesTests { + for _, test := range cryptTests { cryptStr := fromHex(test.crypt) password := types.NewDatum(test.password) f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Datum{cryptStr, password})) diff --git a/util/encrypt/crypt.go b/util/encrypt/crypt.go index 22fa1a37dbf28..15349b00d285b 100644 --- a/util/encrypt/crypt.go +++ b/util/encrypt/crypt.go @@ -26,24 +26,24 @@ type randStruct struct { func (rs *randStruct) randomInit(password []byte, length int) { // hash password - var nr,add,nr2,tmp uint32 - nr = 1345345333 - add=7 - nr2=0x12345671 + var nr, add, nr2, tmp uint32 + nr = 1345345333 + add = 7 + nr2 = 0x12345671 - for i:=0; i< length; i++ { + for i := 0; i < length; i++ { pswChar := password[i] if pswChar == ' ' || pswChar == '\t' { - continue; + continue } tmp = uint32(pswChar) - nr^= (((nr & 63)+add)*tmp)+ (nr << 8) - nr2+=(nr2 << 8) ^ nr - add+=tmp - } - - seed1 := nr & ((uint32(1) << 31) -uint32(1)) - seed2 := nr2 & ((uint32(1) << 31) -uint32(1)) + nr ^= (((nr & 63) + add) * tmp) + (nr << 8) + nr2 += (nr2 << 8) ^ nr + add += tmp + } + + seed1 := nr & ((uint32(1) << 31) - uint32(1)) + seed2 := nr2 & ((uint32(1) << 31) - uint32(1)) fmt.Println(seed1) fmt.Println(seed2) @@ -59,7 +59,7 @@ func (rs *randStruct) myRand() float64 { rs.seed1 = (rs.seed1*3 + rs.seed2) % rs.maxValue rs.seed2 = (rs.seed1 + rs.seed2 + 33) % rs.maxValue - return ((float64(rs.seed1))/ rs.maxValueDbl) + return ((float64(rs.seed1)) / rs.maxValueDbl) } type SqlCrypt struct { @@ -116,26 +116,26 @@ func (sc *SqlCrypt) decode(str []byte, length int) { } } -func SQLDecode(str string, password string) (string,error) { +func SQLDecode(str string, password string) (string, error) { var sqlCrypt SqlCrypt - + strByte := []byte(str) passwdByte := []byte(password) - sqlCrypt.init(passwdByte,len(passwdByte)) - sqlCrypt.decode(strByte,len(strByte)) + sqlCrypt.init(passwdByte, len(passwdByte)) + sqlCrypt.decode(strByte, len(strByte)) - return string(strByte),nil + return string(strByte), false } func SQLEncode(cryptStr string, password string) (string, error) { var sqlCrypt SqlCrypt - cryptStrByte := []byte(cryptStr) - passwdByte := []byte(password) + cryptStrByte := []byte(cryptStr) + passwdByte := []byte(password) + + sqlCrypt.init(passwdByte, len(passwdByte)) + sqlCrypt.encode(cryptStrByte, len(cryptStrByte)) - sqlCrypt.init(passwdByte,len(passwdByte)) - sqlCrypt.encode(cryptStrByte,len(cryptStrByte)) - - return string(cryptStrByte),nil + return string(cryptStrByte), false } From bdf038b5855981ae15b1c4e13d6a1e8fc401c57d Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Thu, 6 Sep 2018 20:47:52 +0800 Subject: [PATCH 05/13] fix make error --- expression/builtin_encryption.go | 4 ++-- util/encrypt/crypt.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/expression/builtin_encryption.go b/expression/builtin_encryption.go index ada2da3e60862..9983aa9f48d1d 100644 --- a/expression/builtin_encryption.go +++ b/expression/builtin_encryption.go @@ -209,7 +209,7 @@ func (b *builtinDecodeSig) evalString(row chunk.Row) (string, bool, error) { } decodeStr, err := encrypt.SQLDecode(dataStr, passwordStr) - return decodeStr, err, nil + return decodeStr, false, err } type desDecryptFunctionClass struct { @@ -268,7 +268,7 @@ func (b *builtinEncodeSig) evalString(row chunk.Row) (string, bool, error) { } dataStr, err := encrypt.SQLEncode(decodeStr, passwordStr) - return dataStr, err, nil + return dataStr, false, err } type encryptFunctionClass struct { diff --git a/util/encrypt/crypt.go b/util/encrypt/crypt.go index 15349b00d285b..38dc73af6dd71 100644 --- a/util/encrypt/crypt.go +++ b/util/encrypt/crypt.go @@ -125,7 +125,7 @@ func SQLDecode(str string, password string) (string, error) { sqlCrypt.init(passwdByte, len(passwdByte)) sqlCrypt.decode(strByte, len(strByte)) - return string(strByte), false + return string(strByte), nil } func SQLEncode(cryptStr string, password string) (string, error) { @@ -137,5 +137,5 @@ func SQLEncode(cryptStr string, password string) (string, error) { sqlCrypt.init(passwdByte, len(passwdByte)) sqlCrypt.encode(cryptStrByte, len(cryptStrByte)) - return string(cryptStrByte), false + return string(cryptStrByte), nil } From 0a20e3bdc7d4bb68786a3eabe8784d2ebc93d95e Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Thu, 6 Sep 2018 20:59:43 +0800 Subject: [PATCH 06/13] fix again --- util/encrypt/crypt_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/util/encrypt/crypt_test.go b/util/encrypt/crypt_test.go index 4064af3f62599..2d1fba7598ebf 100644 --- a/util/encrypt/crypt_test.go +++ b/util/encrypt/crypt_test.go @@ -41,7 +41,7 @@ func (s *testEncryptSuite) TestSQLDecode(c *C) { continue } c.Assert(err, IsNil, Commentf("%v", t)) - result := toHex([]type(crypted)) + result := toHex([]byte(crypted)) c.Assert(result, Equals, t.expect, Commentf("%v", t)) } } From a1af03548fb9b77cb4d001b7845f77375919128d Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Thu, 6 Sep 2018 21:59:50 +0800 Subject: [PATCH 07/13] add comment to functions --- util/encrypt/crypt.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/util/encrypt/crypt.go b/util/encrypt/crypt.go index 38dc73af6dd71..ff0f1be1d6993 100644 --- a/util/encrypt/crypt.go +++ b/util/encrypt/crypt.go @@ -24,8 +24,9 @@ type randStruct struct { maxValueDbl float64 } +// randomInit random generation structure initialization func (rs *randStruct) randomInit(password []byte, length int) { - // hash password + // Generate binary hash from raw text string var nr, add, nr2, tmp uint32 nr = 1345345333 add = 7 @@ -48,7 +49,7 @@ func (rs *randStruct) randomInit(password []byte, length int) { fmt.Println(seed1) fmt.Println(seed2) - // init rand struct + // New (MySQL 3.21+) random generation structure initialization rs.maxValue = 0x3FFFFFFF rs.maxValueDbl = float64(rs.maxValue) rs.seed1 = seed1 % rs.maxValue @@ -62,7 +63,7 @@ func (rs *randStruct) myRand() float64 { return ((float64(rs.seed1)) / rs.maxValueDbl) } -type SqlCrypt struct { +type SQLCrypt struct { rand randStruct orgRand randStruct @@ -71,7 +72,7 @@ type SqlCrypt struct { shift uint32 } -func (sc *SqlCrypt) init(password []byte, length int) { +func (sc *SQLCrypt) init(password []byte, length int) { sc.rand.randomInit(password, length) for i := 0; i <= 255; i++ { @@ -93,12 +94,12 @@ func (sc *SqlCrypt) init(password []byte, length int) { sc.shift = 0 } -func (sc *SqlCrypt) reinit() { +func (sc *SQLCrypt) reinit() { sc.shift = 0 sc.rand = sc.orgRand } -func (sc *SqlCrypt) encode(str []byte, length int) { +func (sc *SQLCrypt) encode(str []byte, length int) { for i := 0; i < length; i++ { sc.shift ^= uint32(sc.rand.myRand() * 255.0) idx := uint32(str[i]) @@ -107,7 +108,7 @@ func (sc *SqlCrypt) encode(str []byte, length int) { } } -func (sc *SqlCrypt) decode(str []byte, length int) { +func (sc *SQLCrypt) decode(str []byte, length int) { for i := 0; i < length; i++ { sc.shift ^= uint32(sc.rand.myRand() * 255.0) idx := uint32(str[i] ^ byte(sc.shift)) @@ -116,8 +117,9 @@ func (sc *SqlCrypt) decode(str []byte, length int) { } } +//SQLDecode Function to handle the decode() function func SQLDecode(str string, password string) (string, error) { - var sqlCrypt SqlCrypt + var sqlCrypt SQLCrypt strByte := []byte(str) passwdByte := []byte(password) @@ -128,8 +130,9 @@ func SQLDecode(str string, password string) (string, error) { return string(strByte), nil } +// SQLEncode Function to handle the encode() function func SQLEncode(cryptStr string, password string) (string, error) { - var sqlCrypt SqlCrypt + var sqlCrypt SQLCrypt cryptStrByte := []byte(cryptStr) passwdByte := []byte(password) From 86ff091e90f3ec0767e0ba00a61003c00fc52352 Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Thu, 6 Sep 2018 22:10:45 +0800 Subject: [PATCH 08/13] add comment again --- util/encrypt/crypt.go | 1 + 1 file changed, 1 insertion(+) diff --git a/util/encrypt/crypt.go b/util/encrypt/crypt.go index ff0f1be1d6993..97291515f5e8d 100644 --- a/util/encrypt/crypt.go +++ b/util/encrypt/crypt.go @@ -63,6 +63,7 @@ func (rs *randStruct) myRand() float64 { return ((float64(rs.seed1)) / rs.maxValueDbl) } +// SQLCrypt use to store initialization results type SQLCrypt struct { rand randStruct orgRand randStruct From 5c71833e00b6354390084b54e3d6a68e862fd969 Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Fri, 7 Sep 2018 20:08:12 +0800 Subject: [PATCH 09/13] remove debug code, and rename SQLCrypt struct --- util/encrypt/crypt.go | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/util/encrypt/crypt.go b/util/encrypt/crypt.go index 97291515f5e8d..578486f4e9a8a 100644 --- a/util/encrypt/crypt.go +++ b/util/encrypt/crypt.go @@ -13,10 +13,6 @@ package encrypt -import ( - "fmt" -) - type randStruct struct { seed1 uint32 seed2 uint32 @@ -46,9 +42,6 @@ func (rs *randStruct) randomInit(password []byte, length int) { seed1 := nr & ((uint32(1) << 31) - uint32(1)) seed2 := nr2 & ((uint32(1) << 31) - uint32(1)) - fmt.Println(seed1) - fmt.Println(seed2) - // New (MySQL 3.21+) random generation structure initialization rs.maxValue = 0x3FFFFFFF rs.maxValueDbl = float64(rs.maxValue) @@ -63,8 +56,8 @@ func (rs *randStruct) myRand() float64 { return ((float64(rs.seed1)) / rs.maxValueDbl) } -// SQLCrypt use to store initialization results -type SQLCrypt struct { +// sqlCrypt use to store initialization results +type sqlCrypt struct { rand randStruct orgRand randStruct @@ -73,7 +66,7 @@ type SQLCrypt struct { shift uint32 } -func (sc *SQLCrypt) init(password []byte, length int) { +func (sc *sqlCrypt) init(password []byte, length int) { sc.rand.randomInit(password, length) for i := 0; i <= 255; i++ { @@ -95,12 +88,12 @@ func (sc *SQLCrypt) init(password []byte, length int) { sc.shift = 0 } -func (sc *SQLCrypt) reinit() { +func (sc *sqlCrypt) reinit() { sc.shift = 0 sc.rand = sc.orgRand } -func (sc *SQLCrypt) encode(str []byte, length int) { +func (sc *sqlCrypt) encode(str []byte, length int) { for i := 0; i < length; i++ { sc.shift ^= uint32(sc.rand.myRand() * 255.0) idx := uint32(str[i]) @@ -109,7 +102,7 @@ func (sc *SQLCrypt) encode(str []byte, length int) { } } -func (sc *SQLCrypt) decode(str []byte, length int) { +func (sc *sqlCrypt) decode(str []byte, length int) { for i := 0; i < length; i++ { sc.shift ^= uint32(sc.rand.myRand() * 255.0) idx := uint32(str[i] ^ byte(sc.shift)) @@ -120,26 +113,26 @@ func (sc *SQLCrypt) decode(str []byte, length int) { //SQLDecode Function to handle the decode() function func SQLDecode(str string, password string) (string, error) { - var sqlCrypt SQLCrypt + var sc sqlCrypt strByte := []byte(str) passwdByte := []byte(password) - sqlCrypt.init(passwdByte, len(passwdByte)) - sqlCrypt.decode(strByte, len(strByte)) + sc.init(passwdByte, len(passwdByte)) + sc.decode(strByte, len(strByte)) return string(strByte), nil } // SQLEncode Function to handle the encode() function func SQLEncode(cryptStr string, password string) (string, error) { - var sqlCrypt SQLCrypt + var sc sqlCrypt cryptStrByte := []byte(cryptStr) passwdByte := []byte(password) - sqlCrypt.init(passwdByte, len(passwdByte)) - sqlCrypt.encode(cryptStrByte, len(cryptStrByte)) + sc.init(passwdByte, len(passwdByte)) + sc.encode(cryptStrByte, len(cryptStrByte)) return string(cryptStrByte), nil } From 761a3529d5eef0ed50d7ed60c8289e3226a363f9 Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Sat, 8 Sep 2018 08:32:24 +0800 Subject: [PATCH 10/13] add some cases for NULL inputs and other conditions --- expression/builtin_encryption_test.go | 7 +++++++ util/encrypt/crypt_test.go | 8 ++++++++ 2 files changed, 15 insertions(+) diff --git a/expression/builtin_encryption_test.go b/expression/builtin_encryption_test.go index b6431888dea19..10cd1b45b5234 100644 --- a/expression/builtin_encryption_test.go +++ b/expression/builtin_encryption_test.go @@ -37,6 +37,13 @@ var cryptTests = []struct { {"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221"}, {"pingcap#%$%^", "*^%YTu1234567", "8634B9C55FF55E5B6328F449"}, {"pingcap", "", "4A77B524BD2C5C"}, + {"分布式データベース","pass1234@#$%%^^&","80CADC8D328B3026D04FB285F36FED04BBCA0CC685BF78B1E687CE"}, + {"分布式データベース","分布式7782734adgwy1242","0E24CFEF272EE32B6E0BFBDB89F29FB43B4B30DAA95C3F914444BC"}, + {"pingcap","密匙","CE5C02A5010010"}, + {"pingcap数据库","数据库passwd12345667","36D5F90D3834E30E396BE3226E3B4ED3"}, + {7382.3456,"数据库passwd12345667","B6484047F783239225"}, + {"数据库",nil,nil}, + {nil,"数据库passwd12345667",nil}, } func (s *testEvaluatorSuite) TestSQLDecode(c *C) { diff --git a/util/encrypt/crypt_test.go b/util/encrypt/crypt_test.go index 2d1fba7598ebf..a44b27277bd79 100644 --- a/util/encrypt/crypt_test.go +++ b/util/encrypt/crypt_test.go @@ -32,6 +32,10 @@ func (s *testEncryptSuite) TestSQLDecode(c *C) { {"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221", false}, {"pingcap#%$%^", "*^%YTu1234567", "8634B9C55FF55E5B6328F449", false}, {"pingcap", "", "4A77B524BD2C5C", false}, + {"分布式データベース","pass1234@#$%%^^&","80CADC8D328B3026D04FB285F36FED04BBCA0CC685BF78B1E687CE",false}, + {"分布式データベース","分布式7782734adgwy1242","0E24CFEF272EE32B6E0BFBDB89F29FB43B4B30DAA95C3F914444BC",false}, + {"pingcap","密匙","CE5C02A5010010",false}, + {"pingcap数据库","数据库passwd12345667","36D5F90D3834E30E396BE3226E3B4ED3",false}, } for _, t := range tests { @@ -60,6 +64,10 @@ func (s *testEncryptSuite) TestSQLEncode(c *C) { {"pingcap123", "123456789012345678901234", "pingcap123", false}, {"pingcap#%$%^", "*^%YTu1234567", "pingcap#%$%^", false}, {"pingcap", "", "pingcap", false}, + {"分布式データベース","pass1234@#$%%^^&","分布式データベース",false}, + {"分布式データベース","分布式7782734adgwy1242","分布式データベース",false}, + {"pingcap","密匙","pingcap",false}, + {"pingcap数据库","数据库passwd12345667","pingcap数据库",false}, } for _, t := range tests { From f9f7c97779d2b9bd7885edcf29b61460623722d0 Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Sat, 8 Sep 2018 10:06:39 +0800 Subject: [PATCH 11/13] fix err --- expression/builtin_encryption_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/expression/builtin_encryption_test.go b/expression/builtin_encryption_test.go index 10cd1b45b5234..334d2d9154f76 100644 --- a/expression/builtin_encryption_test.go +++ b/expression/builtin_encryption_test.go @@ -41,7 +41,7 @@ var cryptTests = []struct { {"分布式データベース","分布式7782734adgwy1242","0E24CFEF272EE32B6E0BFBDB89F29FB43B4B30DAA95C3F914444BC"}, {"pingcap","密匙","CE5C02A5010010"}, {"pingcap数据库","数据库passwd12345667","36D5F90D3834E30E396BE3226E3B4ED3"}, - {7382.3456,"数据库passwd12345667","B6484047F783239225"}, + {"数据库5667",123.435,"B22196D0569386237AE12F8AAB"}, {"数据库",nil,nil}, {nil,"数据库passwd12345667",nil}, } @@ -52,6 +52,7 @@ func (s *testEvaluatorSuite) TestSQLDecode(c *C) { for _, tt := range cryptTests { str := types.NewDatum(tt.origin) password := types.NewDatum(tt.password) + f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Datum{str, password})) crypt, err := evalBuiltinFunc(f, chunk.Row{}) c.Assert(err, IsNil) @@ -63,10 +64,12 @@ func (s *testEvaluatorSuite) TestSQLEncode(c *C) { defer testleak.AfterTest(c)() fc := funcs[ast.Encode] for _, test := range cryptTests { - cryptStr := fromHex(test.crypt) password := types.NewDatum(test.password) + cryptStr := fromHex(test.crypt) + f, err := fc.getFunction(s.ctx, s.datumsToConstants([]types.Datum{cryptStr, password})) str, err := evalBuiltinFunc(f, chunk.Row{}) + c.Assert(err, IsNil) c.Assert(str, DeepEquals, types.NewDatum(test.origin)) } From 9e8b06f98d6663254b248c0003838a3910b7bfba Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Sat, 8 Sep 2018 10:22:06 +0800 Subject: [PATCH 12/13] fix err again --- expression/builtin_encryption_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/expression/builtin_encryption_test.go b/expression/builtin_encryption_test.go index 334d2d9154f76..42d2029e0c3f6 100644 --- a/expression/builtin_encryption_test.go +++ b/expression/builtin_encryption_test.go @@ -42,7 +42,6 @@ var cryptTests = []struct { {"pingcap","密匙","CE5C02A5010010"}, {"pingcap数据库","数据库passwd12345667","36D5F90D3834E30E396BE3226E3B4ED3"}, {"数据库5667",123.435,"B22196D0569386237AE12F8AAB"}, - {"数据库",nil,nil}, {nil,"数据库passwd12345667",nil}, } @@ -58,6 +57,7 @@ func (s *testEvaluatorSuite) TestSQLDecode(c *C) { c.Assert(err, IsNil) c.Assert(toHex(crypt), DeepEquals, types.NewDatum(tt.crypt)) } + s.testNullInput(c, ast.Decode) } func (s *testEvaluatorSuite) TestSQLEncode(c *C) { @@ -73,6 +73,7 @@ func (s *testEvaluatorSuite) TestSQLEncode(c *C) { c.Assert(err, IsNil) c.Assert(str, DeepEquals, types.NewDatum(test.origin)) } + s.testNullInput(c, ast.Encode) } var aesTests = []struct { From d77eec753145a72ab27ca3d426d3472bded7af16 Mon Sep 17 00:00:00 2001 From: Emmett <42971249+lanjingquan@users.noreply.github.com> Date: Sat, 8 Sep 2018 10:35:50 +0800 Subject: [PATCH 13/13] fix fmt --- expression/builtin_encryption_test.go | 16 ++++++++-------- util/encrypt/crypt_test.go | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/expression/builtin_encryption_test.go b/expression/builtin_encryption_test.go index 42d2029e0c3f6..6fa7e90e22dc8 100644 --- a/expression/builtin_encryption_test.go +++ b/expression/builtin_encryption_test.go @@ -37,12 +37,12 @@ var cryptTests = []struct { {"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221"}, {"pingcap#%$%^", "*^%YTu1234567", "8634B9C55FF55E5B6328F449"}, {"pingcap", "", "4A77B524BD2C5C"}, - {"分布式データベース","pass1234@#$%%^^&","80CADC8D328B3026D04FB285F36FED04BBCA0CC685BF78B1E687CE"}, - {"分布式データベース","分布式7782734adgwy1242","0E24CFEF272EE32B6E0BFBDB89F29FB43B4B30DAA95C3F914444BC"}, - {"pingcap","密匙","CE5C02A5010010"}, - {"pingcap数据库","数据库passwd12345667","36D5F90D3834E30E396BE3226E3B4ED3"}, - {"数据库5667",123.435,"B22196D0569386237AE12F8AAB"}, - {nil,"数据库passwd12345667",nil}, + {"分布式データベース", "pass1234@#$%%^^&", "80CADC8D328B3026D04FB285F36FED04BBCA0CC685BF78B1E687CE"}, + {"分布式データベース", "分布式7782734adgwy1242", "0E24CFEF272EE32B6E0BFBDB89F29FB43B4B30DAA95C3F914444BC"}, + {"pingcap", "密匙", "CE5C02A5010010"}, + {"pingcap数据库", "数据库passwd12345667", "36D5F90D3834E30E396BE3226E3B4ED3"}, + {"数据库5667", 123.435, "B22196D0569386237AE12F8AAB"}, + {nil, "数据库passwd12345667", nil}, } func (s *testEvaluatorSuite) TestSQLDecode(c *C) { @@ -57,7 +57,7 @@ func (s *testEvaluatorSuite) TestSQLDecode(c *C) { c.Assert(err, IsNil) c.Assert(toHex(crypt), DeepEquals, types.NewDatum(tt.crypt)) } - s.testNullInput(c, ast.Decode) + s.testNullInput(c, ast.Decode) } func (s *testEvaluatorSuite) TestSQLEncode(c *C) { @@ -73,7 +73,7 @@ func (s *testEvaluatorSuite) TestSQLEncode(c *C) { c.Assert(err, IsNil) c.Assert(str, DeepEquals, types.NewDatum(test.origin)) } - s.testNullInput(c, ast.Encode) + s.testNullInput(c, ast.Encode) } var aesTests = []struct { diff --git a/util/encrypt/crypt_test.go b/util/encrypt/crypt_test.go index a44b27277bd79..524bae486aa39 100644 --- a/util/encrypt/crypt_test.go +++ b/util/encrypt/crypt_test.go @@ -32,10 +32,10 @@ func (s *testEncryptSuite) TestSQLDecode(c *C) { {"pingcap123", "123456789012345678901234", "7698723DC6DFE7724221", false}, {"pingcap#%$%^", "*^%YTu1234567", "8634B9C55FF55E5B6328F449", false}, {"pingcap", "", "4A77B524BD2C5C", false}, - {"分布式データベース","pass1234@#$%%^^&","80CADC8D328B3026D04FB285F36FED04BBCA0CC685BF78B1E687CE",false}, - {"分布式データベース","分布式7782734adgwy1242","0E24CFEF272EE32B6E0BFBDB89F29FB43B4B30DAA95C3F914444BC",false}, - {"pingcap","密匙","CE5C02A5010010",false}, - {"pingcap数据库","数据库passwd12345667","36D5F90D3834E30E396BE3226E3B4ED3",false}, + {"分布式データベース", "pass1234@#$%%^^&", "80CADC8D328B3026D04FB285F36FED04BBCA0CC685BF78B1E687CE", false}, + {"分布式データベース", "分布式7782734adgwy1242", "0E24CFEF272EE32B6E0BFBDB89F29FB43B4B30DAA95C3F914444BC", false}, + {"pingcap", "密匙", "CE5C02A5010010", false}, + {"pingcap数据库", "数据库passwd12345667", "36D5F90D3834E30E396BE3226E3B4ED3", false}, } for _, t := range tests { @@ -64,10 +64,10 @@ func (s *testEncryptSuite) TestSQLEncode(c *C) { {"pingcap123", "123456789012345678901234", "pingcap123", false}, {"pingcap#%$%^", "*^%YTu1234567", "pingcap#%$%^", false}, {"pingcap", "", "pingcap", false}, - {"分布式データベース","pass1234@#$%%^^&","分布式データベース",false}, - {"分布式データベース","分布式7782734adgwy1242","分布式データベース",false}, - {"pingcap","密匙","pingcap",false}, - {"pingcap数据库","数据库passwd12345667","pingcap数据库",false}, + {"分布式データベース", "pass1234@#$%%^^&", "分布式データベース", false}, + {"分布式データベース", "分布式7782734adgwy1242", "分布式データベース", false}, + {"pingcap", "密匙", "pingcap", false}, + {"pingcap数据库", "数据库passwd12345667", "pingcap数据库", false}, } for _, t := range tests {