This is an automated email from the ASF dual-hosted git repository.

tianxiaoliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-service-center.git


The following commit(s) were added to refs/heads/master by this push:
     new a334e08  use scrypt to hash password (#898)
a334e08 is described below

commit a334e08dcc49700961d7e96b4e3887d3dfb57517
Author: Shawn <[email protected]>
AuthorDate: Thu Mar 18 15:29:05 2021 +0800

    use scrypt to hash password (#898)
---
 datasource/etcd/account.go                    |  2 +-
 datasource/mongo/account.go                   |  2 +-
 go.mod                                        |  3 ++-
 pkg/privacy/password.go                       | 30 +++++++++++++++++++++++++++
 pkg/privacy/{password.go => password_test.go} | 27 +++++++++++++++---------
 server/service/rbac/authr_plugin.go           |  3 ++-
 server/service/rbac/password.go               | 11 ++--------
 server/service/rbac/rbac_test.go              |  5 +++--
 8 files changed, 58 insertions(+), 25 deletions(-)

diff --git a/datasource/etcd/account.go b/datasource/etcd/account.go
index d954959..064760c 100644
--- a/datasource/etcd/account.go
+++ b/datasource/etcd/account.go
@@ -50,7 +50,7 @@ func (ds *DataSource) CreateAccount(ctx context.Context, a 
*rbac.Account) error
        if exist {
                return datasource.ErrAccountDuplicated
        }
-       a.Password, err = privacy.HashPassword(a.Password)
+       a.Password, err = privacy.ScryptPassword(a.Password)
        if err != nil {
                log.Error("pwd hash failed", err)
                return err
diff --git a/datasource/mongo/account.go b/datasource/mongo/account.go
index c4e816c..effd9e6 100644
--- a/datasource/mongo/account.go
+++ b/datasource/mongo/account.go
@@ -42,7 +42,7 @@ func (ds *DataSource) CreateAccount(ctx context.Context, a 
*rbac.Account) error
        if exist {
                return datasource.ErrAccountDuplicated
        }
-       a.Password, err = privacy.HashPassword(a.Password)
+       a.Password, err = privacy.ScryptPassword(a.Password)
        if err != nil {
                msg := fmt.Sprintf("failed to hash account pwd, account name 
%s", a.Name)
                log.Error(msg, err)
diff --git a/go.mod b/go.mod
index 64ee4d9..18dad51 100644
--- a/go.mod
+++ b/go.mod
@@ -16,6 +16,7 @@ require (
        github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea // v4
        github.com/dgrijalva/jwt-go v3.2.0+incompatible
        github.com/dustin/go-humanize v1.0.0 // indirect
+       github.com/elithrar/simple-scrypt v1.3.0
        github.com/ghodss/yaml v1.0.0
        github.com/go-chassis/cari v0.2.0
        github.com/go-chassis/foundation v0.3.0
@@ -63,7 +64,7 @@ require (
        go.mongodb.org/mongo-driver v1.4.2
        go.uber.org/multierr v1.6.0 // indirect
        go.uber.org/zap v1.10.0
-       golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a
+       golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b
        golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect
        golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect
        golang.org/x/text v0.3.5 // indirect
diff --git a/pkg/privacy/password.go b/pkg/privacy/password.go
index 8e1787d..b84761f 100644
--- a/pkg/privacy/password.go
+++ b/pkg/privacy/password.go
@@ -18,11 +18,19 @@
 package privacy
 
 import (
+       "github.com/apache/servicecomb-service-center/pkg/log"
+       "github.com/elithrar/simple-scrypt"
        "github.com/go-chassis/foundation/stringutil"
        "golang.org/x/crypto/bcrypt"
+       "strings"
+)
+
+const (
+       algBcrypt = "$2a$"
 )
 
 //HashPassword
+//Deprecated: use ScryptPassword, this is only for unit test to test 
compatible with old version
 func HashPassword(pwd string) (string, error) {
        hash, err := bcrypt.GenerateFromPassword([]byte(pwd), 14)
        if err != nil {
@@ -30,3 +38,25 @@ func HashPassword(pwd string) (string, error) {
        }
        return stringutil.Bytes2str(hash), nil
 }
+func ScryptPassword(pwd string) (string, error) {
+       hash, err := scrypt.GenerateFromPassword([]byte(pwd), 
scrypt.DefaultParams)
+       if err != nil {
+               return "", err
+       }
+       return string(hash), nil
+}
+func SamePassword(hashedPwd, pwd string) bool {
+       if strings.HasPrefix(hashedPwd, algBcrypt) {
+               err := bcrypt.CompareHashAndPassword([]byte(hashedPwd), 
[]byte(pwd))
+               if err == bcrypt.ErrMismatchedHashAndPassword {
+                       log.Warn("incorrect password attempts")
+               }
+               return err == nil
+       }
+       err := scrypt.CompareHashAndPassword([]byte(hashedPwd), []byte(pwd))
+       if err == bcrypt.ErrMismatchedHashAndPassword {
+               log.Warn("incorrect password attempts")
+       }
+       return err == nil
+
+}
diff --git a/pkg/privacy/password.go b/pkg/privacy/password_test.go
similarity index 62%
copy from pkg/privacy/password.go
copy to pkg/privacy/password_test.go
index 8e1787d..056f15f 100644
--- a/pkg/privacy/password.go
+++ b/pkg/privacy/password_test.go
@@ -15,18 +15,25 @@
  * limitations under the License.
  */
 
-package privacy
+package privacy_test
 
 import (
-       "github.com/go-chassis/foundation/stringutil"
-       "golang.org/x/crypto/bcrypt"
+       "github.com/apache/servicecomb-service-center/pkg/privacy"
+       "github.com/stretchr/testify/assert"
+       "testing"
 )
 
-//HashPassword
-func HashPassword(pwd string) (string, error) {
-       hash, err := bcrypt.GenerateFromPassword([]byte(pwd), 14)
-       if err != nil {
-               return "", err
-       }
-       return stringutil.Bytes2str(hash), nil
+func TestHashPassword(t *testing.T) {
+       h, _ := privacy.HashPassword("test")
+       t.Log(h)
+       mac, _ := privacy.ScryptPassword("test")
+       t.Log(mac)
+
+       t.Run("given old hash result, should be compatible", func(t *testing.T) 
{
+               same := privacy.SamePassword(h, "test")
+               assert.True(t, same)
+       })
+
+       sameMac := privacy.SamePassword(mac, "test")
+       assert.True(t, sameMac)
 }
diff --git a/server/service/rbac/authr_plugin.go 
b/server/service/rbac/authr_plugin.go
index ffa653d..a8fdbbe 100644
--- a/server/service/rbac/authr_plugin.go
+++ b/server/service/rbac/authr_plugin.go
@@ -20,6 +20,7 @@ package rbac
 import (
        "context"
        "errors"
+       "github.com/apache/servicecomb-service-center/pkg/privacy"
 
        "github.com/apache/servicecomb-service-center/pkg/log"
        "github.com/apache/servicecomb-service-center/pkg/rbacframe"
@@ -58,7 +59,7 @@ func (a *EmbeddedAuthenticator) Login(ctx context.Context, 
user string, password
                log.Error("get account err", err)
                return "", err
        }
-       same := SamePassword(account.Password, password)
+       same := privacy.SamePassword(account.Password, password)
        if user == account.Name && same {
                secret, err := GetPrivateKey()
                if err != nil {
diff --git a/server/service/rbac/password.go b/server/service/rbac/password.go
index 6879043..9a986c2 100644
--- a/server/service/rbac/password.go
+++ b/server/service/rbac/password.go
@@ -19,6 +19,7 @@ package rbac
 
 import (
        "context"
+       "github.com/apache/servicecomb-service-center/pkg/privacy"
        "github.com/apache/servicecomb-service-center/pkg/rbacframe"
        rbacmodel "github.com/go-chassis/cari/rbac"
 
@@ -68,7 +69,7 @@ func changePassword(ctx context.Context, name, 
currentPassword, pwd string) erro
                log.Error("can not change pwd", err)
                return err
        }
-       same := SamePassword(old.Password, currentPassword)
+       same := privacy.SamePassword(old.Password, currentPassword)
        if !same {
                log.Error("current password is wrong", nil)
                return ErrWrongPassword
@@ -94,11 +95,3 @@ func doChangePassword(ctx context.Context, old 
*rbacmodel.Account, pwd string) e
        }
        return nil
 }
-
-func SamePassword(hashedPwd, pwd string) bool {
-       err := bcrypt.CompareHashAndPassword([]byte(hashedPwd), []byte(pwd))
-       if err == bcrypt.ErrMismatchedHashAndPassword {
-               log.Warn("incorrect password attempts")
-       }
-       return err == nil
-}
diff --git a/server/service/rbac/rbac_test.go b/server/service/rbac/rbac_test.go
index b3b5ac9..e4d90e3 100644
--- a/server/service/rbac/rbac_test.go
+++ b/server/service/rbac/rbac_test.go
@@ -19,6 +19,7 @@ package rbac_test
 
 import (
        "context"
+       "github.com/apache/servicecomb-service-center/pkg/privacy"
        "github.com/apache/servicecomb-service-center/pkg/rbacframe"
        "github.com/apache/servicecomb-service-center/server/config"
        "github.com/apache/servicecomb-service-center/server/service/rbac"
@@ -86,7 +87,7 @@ func TestInitRBAC(t *testing.T) {
                assert.NoError(t, err)
                a, err := dao.GetAccount(context.Background(), "a")
                assert.NoError(t, err)
-               assert.True(t, rbac.SamePassword(a.Password, 
"Complicated_password2"))
+               assert.True(t, privacy.SamePassword(a.Password, 
"Complicated_password2"))
        })
        t.Run("change self password", func(t *testing.T) {
                err := dao.CreateAccount(context.Background(), 
&rbacmodel.Account{Name: "b", Password: "Complicated_password1"})
@@ -95,7 +96,7 @@ func TestInitRBAC(t *testing.T) {
                assert.NoError(t, err)
                a, err := dao.GetAccount(context.Background(), "b")
                assert.NoError(t, err)
-               assert.True(t, rbac.SamePassword(a.Password, 
"Complicated_password2"))
+               assert.True(t, privacy.SamePassword(a.Password, 
"Complicated_password2"))
 
        })
        t.Run("list kv", func(t *testing.T) {

Reply via email to