From fad5f11d5d2347b98561ccaa0ee91cb270f4619e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=8C=E4=B8=AB=E8=AE=B2=E6=A2=B5?= Date: Tue, 9 May 2023 18:06:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B9=B3=E5=8F=B0=E4=B8=AD=E5=88=9B?= =?UTF-8?q?=E5=BB=BA=E7=9A=84=E7=94=A8=E6=88=B7=E5=AF=86=E7=A0=81=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E4=BD=BF=E7=94=A8ssha=E5=8A=A0=E5=AF=86=E7=AD=96?= =?UTF-8?q?=E7=95=A5=20(#208)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .pre-commit-config.yaml | 2 +- README.md | 2 +- public/tools/ssha.go | 53 +++++++++++++++++++++++++++++++++++++ public/tools/util_test.go | 12 +++++++++ service/ildap/user_ildap.go | 2 +- 5 files changed, 68 insertions(+), 3 deletions(-) create mode 100644 public/tools/ssha.go diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 199af1e..fd8fe86 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,7 +6,7 @@ repos: - id: trailing-whitespace - id: check-added-large-files - repo: https://github.com/golangci/golangci-lint # golangci-lint hook repo - rev: v1.47.3 # golangci-lint hook repo revision + rev: v1.52.2 # golangci-lint hook repo revision hooks: - id: golangci-lint name: golangci-lint diff --git a/README.md b/README.md index a5e07a8..5f986dd 100644 --- a/README.md +++ b/README.md @@ -161,7 +161,7 @@ ckyoung123421
- Null + ckyoung123421
diff --git a/public/tools/ssha.go b/public/tools/ssha.go new file mode 100644 index 0000000..2c8b8d8 --- /dev/null +++ b/public/tools/ssha.go @@ -0,0 +1,53 @@ +package tools + +import ( + "bytes" + "crypto/sha1" + "encoding/base64" + "fmt" + "math/rand" +) + +// code from https://gist.github.com/newm4n/ce9ac4308ae1beb4250efddad28e3f85 + +// Encode encodes the []byte of raw password +func EncodePass(rawPassPhrase []byte) string { + hash := makeSSHAHash(rawPassPhrase, makeSalt()) + b64 := base64.StdEncoding.EncodeToString(hash) + return string([]byte(fmt.Sprintf("{SSHA}%s", b64))) +} + +// makeSalt make a 4 byte array containing random bytes. +func makeSalt() []byte { + sbytes := make([]byte, 4) + rand.Read(sbytes) + return sbytes +} + +// makeSSHAHash make hasing using SHA-1 with salt. This is not the final output though. You need to append {SSHA} string with base64 of this hash. +func makeSSHAHash(passphrase, salt []byte) []byte { + sha := sha1.New() + sha.Write(passphrase) + sha.Write(salt) + + h := sha.Sum(nil) + return append(h, salt...) +} + +// Matches matches the encoded password and the raw password +func Matches(encodedPassPhrase, rawPassPhrase []byte) bool { + //strip the {SSHA} + eppS := string(encodedPassPhrase)[6:] + hash, err := base64.StdEncoding.DecodeString(eppS) + if err != nil { + return false + } + salt := hash[len(hash)-4:] + + sha := sha1.New() + sha.Write(rawPassPhrase) + sha.Write(salt) + sum := sha.Sum(nil) + + return bytes.Equal(sum, hash[:len(hash)-4]) +} diff --git a/public/tools/util_test.go b/public/tools/util_test.go index 90b9a0b..4ebfe4e 100644 --- a/public/tools/util_test.go +++ b/public/tools/util_test.go @@ -25,3 +25,15 @@ func TestSliceToString(t *testing.T) { a := []uint{1} fmt.Printf("%s\n", SliceToString(a, ",")) } + +func TestEncodePass(t *testing.T) { + // to encode a password into ssha + hashed := EncodePass([]byte("testpass")) + fmt.Println(string(hashed)) + // to validate a password against saved hash. + if Matches([]byte(hashed), []byte("testpass")) { + fmt.Println("Its a match.") + } else { + fmt.Println("its not match") + } +} diff --git a/service/ildap/user_ildap.go b/service/ildap/user_ildap.go index 607018e..8b3683a 100644 --- a/service/ildap/user_ildap.go +++ b/service/ildap/user_ildap.go @@ -29,7 +29,7 @@ func (x UserService) Add(user *model.User) error { add.Attribute("postalAddress", []string{user.PostalAddress}) add.Attribute("mobile", []string{user.Mobile}) add.Attribute("uid", []string{user.Username}) - add.Attribute("userPassword", []string{tools.NewParPasswd(user.Password)}) + add.Attribute("userPassword", []string{tools.EncodePass([]byte(tools.NewParPasswd(user.Password)))}) // 获取 LDAP 连接 conn, err := common.GetLDAPConn()