You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
3.2 KiB
133 lines
3.2 KiB
// 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
|
|
|
|
type randStruct struct {
|
|
seed1 uint32
|
|
seed2 uint32
|
|
maxValue uint32
|
|
maxValueDbl float64
|
|
}
|
|
|
|
// randomInit random generation structure initialization
|
|
func (rs *randStruct) randomInit(password []byte, length int) {
|
|
// Generate binary hash from raw text string
|
|
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))
|
|
|
|
// New (MySQL 3.21+) random generation structure initialization
|
|
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)
|
|
}
|
|
|
|
// sqlCrypt use to store initialization results
|
|
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) 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])
|
|
}
|
|
}
|
|
|
|
// SQLDecode Function to handle the decode() function
|
|
func SQLDecode(str string, password string) (string, error) {
|
|
var sc sqlCrypt
|
|
|
|
strByte := []byte(str)
|
|
passwdByte := []byte(password)
|
|
|
|
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 sc sqlCrypt
|
|
|
|
cryptStrByte := []byte(cryptStr)
|
|
passwdByte := []byte(password)
|
|
|
|
sc.init(passwdByte, len(passwdByte))
|
|
sc.encode(cryptStrByte, len(cryptStrByte))
|
|
|
|
return string(cryptStrByte), nil
|
|
}
|
|
|