Merge pull request #119 from owncloud/change-hashing-algorithm

change hashing algorithm from SHA-512 to bcrypt
This commit is contained in:
David Christofas
2020-09-17 09:31:56 +02:00
committed by GitHub
4 changed files with 27 additions and 19 deletions
@@ -0,0 +1,7 @@
Change: Use bcrypt to hash the user passwords
Change the hashing algorithm from SHA-512 to bcrypt since the latter is better suitable for password hashing.
This is a breaking change. Existing deployments need to regenerate the accounts folder.
https://github.com/owncloud/ocis/issues/510
+11 -13
View File
@@ -23,15 +23,13 @@ import (
settings "github.com/owncloud/ocis-settings/pkg/proto/v0" settings "github.com/owncloud/ocis-settings/pkg/proto/v0"
settings_svc "github.com/owncloud/ocis-settings/pkg/service/v0" settings_svc "github.com/owncloud/ocis-settings/pkg/service/v0"
"github.com/rs/zerolog" "github.com/rs/zerolog"
"github.com/tredoe/osutil/user/crypt" "golang.org/x/crypto/bcrypt"
"google.golang.org/genproto/protobuf/field_mask" "google.golang.org/genproto/protobuf/field_mask"
"google.golang.org/protobuf/types/known/timestamppb" "google.golang.org/protobuf/types/known/timestamppb"
)
// register crypt functions const (
_ "github.com/tredoe/osutil/user/crypt/apr1_crypt" _hashDifficulty = 12
_ "github.com/tredoe/osutil/user/crypt/md5_crypt"
_ "github.com/tredoe/osutil/user/crypt/sha256_crypt"
_ "github.com/tredoe/osutil/user/crypt/sha512_crypt"
) )
// accLock mutually exclude readers from writers on account files // accLock mutually exclude readers from writers on account files
@@ -153,8 +151,7 @@ func (s Service) passwordIsValid(hash string, pwd string) (ok bool) {
} }
}() }()
c := crypt.NewFromHash(hash) return bcrypt.CompareHashAndPassword([]byte(hash), []byte(pwd)) == nil
return c.Verify(hash, []byte(pwd)) == nil
} }
func (s Service) accountExists(ctx context.Context, username, mail, id string) (exists bool, err error) { func (s Service) accountExists(ctx context.Context, username, mail, id string) (exists bool, err error) {
@@ -373,11 +370,12 @@ func (s Service) CreateAccount(ctx context.Context, in *proto.CreateAccountReque
if acc.PasswordProfile != nil { if acc.PasswordProfile != nil {
if acc.PasswordProfile.Password != "" { if acc.PasswordProfile.Password != "" {
// encrypt password // encrypt password
c := crypt.New(crypt.SHA512) hashed, err := bcrypt.GenerateFromPassword([]byte(acc.PasswordProfile.Password), _hashDifficulty)
if acc.PasswordProfile.Password, err = c.Generate([]byte(acc.PasswordProfile.Password), nil); err != nil { if err != nil {
s.log.Error().Err(err).Str("id", id).Msg("could not hash password") s.log.Error().Err(err).Str("id", id).Msg("could not hash password")
return merrors.InternalServerError(s.id, "could not hash password: %v", err.Error()) return merrors.InternalServerError(s.id, "could not hash password: %v", err.Error())
} }
acc.PasswordProfile.Password = string(hashed)
} }
if err := passwordPoliciesValid(acc.PasswordProfile.PasswordPolicies); err != nil { if err := passwordPoliciesValid(acc.PasswordProfile.PasswordPolicies); err != nil {
@@ -476,13 +474,13 @@ func (s Service) UpdateAccount(ctx context.Context, in *proto.UpdateAccountReque
} }
if in.Account.PasswordProfile.Password != "" { if in.Account.PasswordProfile.Password != "" {
// encrypt password // encrypt password
c := crypt.New(crypt.SHA512) hashed, err := bcrypt.GenerateFromPassword([]byte(in.Account.PasswordProfile.Password), _hashDifficulty)
if out.PasswordProfile.Password, err = c.Generate([]byte(in.Account.PasswordProfile.Password), nil); err != nil { if err != nil {
in.Account.PasswordProfile.Password = "" in.Account.PasswordProfile.Password = ""
s.log.Error().Err(err).Str("id", id).Msg("could not hash password") s.log.Error().Err(err).Str("id", id).Msg("could not hash password")
return merrors.InternalServerError(s.id, "could not hash password: %v", err.Error()) return merrors.InternalServerError(s.id, "could not hash password: %v", err.Error())
} }
out.PasswordProfile.Password = string(hashed)
in.Account.PasswordProfile.Password = "" in.Account.PasswordProfile.Password = ""
} }
+6 -6
View File
@@ -187,7 +187,7 @@ func (s Service) createDefaultAccounts(accountsDir string) (err error) {
UidNumber: 20000, UidNumber: 20000,
GidNumber: 30000, GidNumber: 30000,
PasswordProfile: &proto.PasswordProfile{ PasswordProfile: &proto.PasswordProfile{
Password: "$6$rounds=35210$sa1u5Pmfo4cr23Vw$RJNGElaDB1D3xorWkfTEGm2Ko.o2QL3E0cimKx23MNxVWVFSkUUeRoC7FqC4RzYDNQBD6cKzovTEaDD.8TDkD.", Password: "$2a$12$qGho4QmaDn4HifisABQ2ROBc41TUCIBNrqwOg3zPEYednDWkXHOKG",
}, },
AccountEnabled: true, AccountEnabled: true,
MemberOf: []*proto.Group{ MemberOf: []*proto.Group{
@@ -206,7 +206,7 @@ func (s Service) createDefaultAccounts(accountsDir string) (err error) {
UidNumber: 20001, UidNumber: 20001,
GidNumber: 30000, GidNumber: 30000,
PasswordProfile: &proto.PasswordProfile{ PasswordProfile: &proto.PasswordProfile{
Password: "$6$rounds=81434$sa1u5Pmfo4cr23Vw$W78cyL884GmuvDpxYPvSRBVzEj02T5QhTTcI8Dv4IKvMooDFGv4bwaWMkH9HfJ0wgpEBW7Lp.4Cad0xE/MYSg1", Password: "$2a$12$JzfOtyRiGL25w1UpmiPZ1uU7KJURoTMPSRlZQvMB90/1zqvjwEWgO",
}, },
AccountEnabled: true, AccountEnabled: true,
MemberOf: []*proto.Group{ MemberOf: []*proto.Group{
@@ -225,7 +225,7 @@ func (s Service) createDefaultAccounts(accountsDir string) (err error) {
UidNumber: 20002, UidNumber: 20002,
GidNumber: 30000, GidNumber: 30000,
PasswordProfile: &proto.PasswordProfile{ PasswordProfile: &proto.PasswordProfile{
Password: "$6$rounds=5524$sa1u5Pmfo4cr23Vw$58bQVL/JeUlwM0RY21YKAFMvKvwKLLysGllYXox.vwKT5dHMwdzJjCxwTDMnB2o2pwexC8o/iOXyP2zrhALS40", Password: "$2a$12$bWMHNfc92rDForMapNle/eJ1fOY0eTeRzpk1EQFUdKGI6UdTktp/a",
}, },
AccountEnabled: true, AccountEnabled: true,
MemberOf: []*proto.Group{ MemberOf: []*proto.Group{
@@ -245,7 +245,7 @@ func (s Service) createDefaultAccounts(accountsDir string) (err error) {
UidNumber: 20003, UidNumber: 20003,
GidNumber: 30000, GidNumber: 30000,
PasswordProfile: &proto.PasswordProfile{ PasswordProfile: &proto.PasswordProfile{
Password: "$6$rounds=47068$lhw6odzXW0LTk/ao$GgxS.pIgP8jawLJBAiyNor2FrWzrULF95PwspRkli2W3VF.4HEwTYlQfRXbNQBMjNCEcEYlgZo3a.kRz2k2N0/", Password: "$2a$12$TY7jDd1PNbZXzZJMvIFm3eXAL4wjzOl.QXJZ6GKGDpAmUcvHBNc66",
}, },
AccountEnabled: true, AccountEnabled: true,
MemberOf: []*proto.Group{ MemberOf: []*proto.Group{
@@ -262,7 +262,7 @@ func (s Service) createDefaultAccounts(accountsDir string) (err error) {
UidNumber: 10000, UidNumber: 10000,
GidNumber: 15000, GidNumber: 15000,
PasswordProfile: &proto.PasswordProfile{ PasswordProfile: &proto.PasswordProfile{
Password: "$6$rounds=9746$sa1u5Pmfo4cr23Vw$2hnwpkTvUkWX0v6mh8Aw1pbzEXa9EUJzmrey4g2W/8arwWCwhteqU//3aWnA3S0d5T21fOKYteoqlsN1IbTcN.", Password: "$2a$12$pV8JlGlpM9oo1RaC7kSg/uBTFoTOJ8XfjibFL2U4gOpPKVfbD6pUG",
}, },
AccountEnabled: true, AccountEnabled: true,
MemberOf: []*proto.Group{ MemberOf: []*proto.Group{
@@ -278,7 +278,7 @@ func (s Service) createDefaultAccounts(accountsDir string) (err error) {
UidNumber: 10001, UidNumber: 10001,
GidNumber: 15000, GidNumber: 15000,
PasswordProfile: &proto.PasswordProfile{ PasswordProfile: &proto.PasswordProfile{
Password: "$6$rounds=91087$sa1u5Pmfo4cr23Vw$wPC3BbMTbP/ytlo0p.f99zJifyO70AUCdKIK9hkhwutBKGCirLmZs/MsWAG6xHjVvmnmHN5NoON7FUGv5pPaN.", Password: "$2a$12$CSM.vkX9o7lO/uvid3XieOVtmq5nh91MFZHvHIsfRms3hLzTa2W6.",
}, },
AccountEnabled: true, AccountEnabled: true,
MemberOf: []*proto.Group{ MemberOf: []*proto.Group{
@@ -30,9 +30,12 @@ module.exports = {
util.format(this.elements.roleInRolesDropdown.selector, role) util.format(this.elements.roleInRolesDropdown.selector, role)
return this return this
.initAjaxCounters()
.waitForElementVisible('@rolesDropdownTrigger')
.click('@rolesDropdownTrigger') .click('@rolesDropdownTrigger')
.waitForElementVisible(roleSelector) .waitForElementVisible(roleSelector)
.click(roleSelector) .click(roleSelector)
.waitForOutstandingAjaxCalls()
}, },
checkUsersRole: function (username, role) { checkUsersRole: function (username, role) {