feat(crypto): support md5 salted for imported password hashes (#9596)

# Which Problems Are Solved

Allow verification of imported salted passwords hashed with plain md5.

# How the Problems Are Solved

- Upgrade passwap to
[v0.7.0](https://github.com/zitadel/passwap/releases/tag/v0.7.0)
- Add md5salted as a new verifier option in `defaults.yaml`

# Additional Changes

- go version and libraries updated  (required by passkey v0.7.0)
- secrets.md verifiers updated  
- configuration verifiers updated 
- added MD5salted and missing MD5Plain to test cases
This commit is contained in:
Miro Trisc 2025-03-21 13:25:52 +01:00 committed by GitHub
parent dc64e35128
commit e4c12864e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 70 additions and 32 deletions

View File

@ -697,6 +697,7 @@ SystemDefaults:
# - "bcrypt" # - "bcrypt"
# - "md5" # md5Crypt with salt and password shuffling. # - "md5" # md5Crypt with salt and password shuffling.
# - "md5plain" # md5 digest of a password without salt # - "md5plain" # md5 digest of a password without salt
# - "md5salted" # md5 digest of a salted password
# - "scrypt" # - "scrypt"
# - "pbkdf2" # verifier for all pbkdf2 hash modes. # - "pbkdf2" # verifier for all pbkdf2 hash modes.
SecretHasher: SecretHasher:

View File

@ -70,6 +70,7 @@ The following hash algorithms are supported:
- bcrypt (Default) - bcrypt (Default)
- md5: implementation of md5Crypt with salt and password shuffling [^2] - md5: implementation of md5Crypt with salt and password shuffling [^2]
- md5plain: md5 digest of a password without salt [^2] - md5plain: md5 digest of a password without salt [^2]
- md5salted: md5 digest of a salted password [^2]
- scrypt - scrypt
- pbkdf2 - pbkdf2

12
go.mod
View File

@ -1,6 +1,6 @@
module github.com/zitadel/zitadel module github.com/zitadel/zitadel
go 1.23.4 go 1.23.7
require ( require (
cloud.google.com/go/profiler v0.4.1 cloud.google.com/go/profiler v0.4.1
@ -72,7 +72,7 @@ require (
github.com/twilio/twilio-go v1.22.2 github.com/twilio/twilio-go v1.22.2
github.com/zitadel/logging v0.6.1 github.com/zitadel/logging v0.6.1
github.com/zitadel/oidc/v3 v3.32.0 github.com/zitadel/oidc/v3 v3.32.0
github.com/zitadel/passwap v0.6.0 github.com/zitadel/passwap v0.7.0
github.com/zitadel/saml v0.3.4 github.com/zitadel/saml v0.3.4
github.com/zitadel/schema v1.3.0 github.com/zitadel/schema v1.3.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0
@ -86,12 +86,12 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.29.0 go.opentelemetry.io/otel/sdk/metric v1.29.0
go.opentelemetry.io/otel/trace v1.29.0 go.opentelemetry.io/otel/trace v1.29.0
go.uber.org/mock v0.5.0 go.uber.org/mock v0.5.0
golang.org/x/crypto v0.31.0 golang.org/x/crypto v0.36.0
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
golang.org/x/net v0.33.0 golang.org/x/net v0.33.0
golang.org/x/oauth2 v0.23.0 golang.org/x/oauth2 v0.23.0
golang.org/x/sync v0.11.0 golang.org/x/sync v0.12.0
golang.org/x/text v0.21.0 golang.org/x/text v0.23.0
google.golang.org/api v0.187.0 google.golang.org/api v0.187.0
google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd google.golang.org/genproto/googleapis/api v0.0.0-20240822170219-fc7c04adadcd
google.golang.org/grpc v1.65.0 google.golang.org/grpc v1.65.0
@ -216,7 +216,7 @@ require (
go.opencensus.io v0.24.0 // indirect go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.29.0 // indirect
go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.opentelemetry.io/proto/otlp v1.3.1 // indirect
golang.org/x/sys v0.28.0 golang.org/x/sys v0.31.0
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

10
go.sum
View File

@ -778,6 +778,8 @@ github.com/zitadel/oidc/v3 v3.32.0 h1:Mw0EPZRC6h+OXAuT0Uk2BZIjJQNHLqUpaJCm6c3IBy
github.com/zitadel/oidc/v3 v3.32.0/go.mod h1:DyE/XClysRK/ozFaZSqlYamKVnTh4l6Ln25ihSNI03w= github.com/zitadel/oidc/v3 v3.32.0/go.mod h1:DyE/XClysRK/ozFaZSqlYamKVnTh4l6Ln25ihSNI03w=
github.com/zitadel/passwap v0.6.0 h1:m9F3epFC0VkBXu25rihSLGyHvWiNlCzU5kk8RoI+SXQ= github.com/zitadel/passwap v0.6.0 h1:m9F3epFC0VkBXu25rihSLGyHvWiNlCzU5kk8RoI+SXQ=
github.com/zitadel/passwap v0.6.0/go.mod h1:kqAiJ4I4eZvm3Y6oAk6hlEqlZZOkjMHraGXF90GG7LI= github.com/zitadel/passwap v0.6.0/go.mod h1:kqAiJ4I4eZvm3Y6oAk6hlEqlZZOkjMHraGXF90GG7LI=
github.com/zitadel/passwap v0.7.0 h1:TQTr9TV75PLATGICor1g5hZDRNHRvB9t0Hn4XkiR7xQ=
github.com/zitadel/passwap v0.7.0/go.mod h1:/NakQNYahdU+YFEitVD6mlm8BLfkiIT+IM5wgClRoAY=
github.com/zitadel/saml v0.3.4 h1:L2pybnx2Hs+kqebZmUbnZUd9L/CY2sNw5psMWw2D/6Q= github.com/zitadel/saml v0.3.4 h1:L2pybnx2Hs+kqebZmUbnZUd9L/CY2sNw5psMWw2D/6Q=
github.com/zitadel/saml v0.3.4/go.mod h1:M0losAULJpLtAmXrYqBnf375ia2rMgJ75b1mpaU/GlA= github.com/zitadel/saml v0.3.4/go.mod h1:M0losAULJpLtAmXrYqBnf375ia2rMgJ75b1mpaU/GlA=
github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0= github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0=
@ -846,6 +848,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U=
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
@ -927,6 +931,8 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -971,6 +977,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -987,6 +995,8 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=

View File

@ -12,6 +12,7 @@ import (
"github.com/zitadel/passwap/bcrypt" "github.com/zitadel/passwap/bcrypt"
"github.com/zitadel/passwap/md5" "github.com/zitadel/passwap/md5"
"github.com/zitadel/passwap/md5plain" "github.com/zitadel/passwap/md5plain"
"github.com/zitadel/passwap/md5salted"
"github.com/zitadel/passwap/pbkdf2" "github.com/zitadel/passwap/pbkdf2"
"github.com/zitadel/passwap/scrypt" "github.com/zitadel/passwap/scrypt"
"github.com/zitadel/passwap/verifier" "github.com/zitadel/passwap/verifier"
@ -49,6 +50,7 @@ const (
HashNameBcrypt HashName = "bcrypt" // hash and verify HashNameBcrypt HashName = "bcrypt" // hash and verify
HashNameMd5 HashName = "md5" // verify only, as hashing with md5 is insecure and deprecated HashNameMd5 HashName = "md5" // verify only, as hashing with md5 is insecure and deprecated
HashNameMd5Plain HashName = "md5plain" // verify only, as hashing with md5 is insecure and deprecated HashNameMd5Plain HashName = "md5plain" // verify only, as hashing with md5 is insecure and deprecated
HashNameMd5Salted HashName = "md5salted" // verify only, as hashing with md5 is insecure and deprecated
HashNameScrypt HashName = "scrypt" // hash and verify HashNameScrypt HashName = "scrypt" // hash and verify
HashNamePBKDF2 HashName = "pbkdf2" // hash and verify HashNamePBKDF2 HashName = "pbkdf2" // hash and verify
) )
@ -119,6 +121,10 @@ var knowVerifiers = map[HashName]prefixVerifier{
prefixes: []string{pbkdf2.Prefix}, prefixes: []string{pbkdf2.Prefix},
verifier: pbkdf2.Verifier, verifier: pbkdf2.Verifier,
}, },
HashNameMd5Salted: {
prefixes: []string{md5salted.Prefix},
verifier: md5salted.Verifier,
},
} }
func (c *HashConfig) buildVerifiers() (verifiers []verifier.Verifier, prefixes []string, err error) { func (c *HashConfig) buildVerifiers() (verifiers []verifier.Verifier, prefixes []string, err error) {

View File

@ -11,6 +11,7 @@ import (
"github.com/zitadel/passwap/argon2" "github.com/zitadel/passwap/argon2"
"github.com/zitadel/passwap/bcrypt" "github.com/zitadel/passwap/bcrypt"
"github.com/zitadel/passwap/md5" "github.com/zitadel/passwap/md5"
"github.com/zitadel/passwap/md5salted"
"github.com/zitadel/passwap/pbkdf2" "github.com/zitadel/passwap/pbkdf2"
"github.com/zitadel/passwap/scrypt" "github.com/zitadel/passwap/scrypt"
) )
@ -76,6 +77,7 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
HashNameArgon2, HashNameArgon2,
HashNameBcrypt, HashNameBcrypt,
HashNameMd5, HashNameMd5,
HashNameMd5Salted,
HashNameScrypt, HashNameScrypt,
"foobar", "foobar",
}, },
@ -122,6 +124,24 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
}, },
wantErr: true, wantErr: true,
}, },
{
name: "invalid md5plain",
fields: fields{
Hasher: HasherConfig{
Algorithm: HashNameMd5Plain,
},
},
wantErr: true,
},
{
name: "invalid md5salted",
fields: fields{
Hasher: HasherConfig{
Algorithm: HashNameMd5Salted,
},
},
wantErr: true,
},
{ {
name: "invalid argon2", name: "invalid argon2",
fields: fields{ fields: fields{
@ -160,9 +180,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"threads": 4, "threads": 4,
}, },
}, },
Verifiers: []HashName{HashNameBcrypt, HashNameMd5, HashNameScrypt}, Verifiers: []HashName{HashNameBcrypt, HashNameMd5, HashNameScrypt, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{argon2.Prefix, bcrypt.Prefix, md5.Prefix, scrypt.Prefix, scrypt.Prefix_Linux}, wantPrefixes: []string{argon2.Prefix, bcrypt.Prefix, md5.Prefix, scrypt.Prefix, scrypt.Prefix_Linux, md5salted.Prefix},
}, },
{ {
name: "argon2id, error", name: "argon2id, error",
@ -188,9 +208,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"threads": 4, "threads": 4,
}, },
}, },
Verifiers: []HashName{HashNameBcrypt, HashNameMd5, HashNameScrypt}, Verifiers: []HashName{HashNameBcrypt, HashNameMd5, HashNameScrypt, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{argon2.Prefix, bcrypt.Prefix, md5.Prefix, scrypt.Prefix, scrypt.Prefix_Linux}, wantPrefixes: []string{argon2.Prefix, bcrypt.Prefix, md5.Prefix, scrypt.Prefix, scrypt.Prefix_Linux, md5salted.Prefix},
}, },
{ {
name: "bcrypt, error", name: "bcrypt, error",
@ -213,9 +233,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"cost": 3, "cost": 3,
}, },
}, },
Verifiers: []HashName{HashNameArgon2, HashNameMd5, HashNameScrypt}, Verifiers: []HashName{HashNameArgon2, HashNameMd5, HashNameScrypt, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{bcrypt.Prefix, argon2.Prefix, md5.Prefix, scrypt.Prefix, scrypt.Prefix_Linux}, wantPrefixes: []string{bcrypt.Prefix, argon2.Prefix, md5.Prefix, scrypt.Prefix, scrypt.Prefix_Linux, md5salted.Prefix},
}, },
{ {
name: "scrypt, error", name: "scrypt, error",
@ -238,9 +258,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"cost": 3, "cost": 3,
}, },
}, },
Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5}, Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{scrypt.Prefix, scrypt.Prefix_Linux, argon2.Prefix, bcrypt.Prefix, md5.Prefix}, wantPrefixes: []string{scrypt.Prefix, scrypt.Prefix_Linux, argon2.Prefix, bcrypt.Prefix, md5.Prefix, md5salted.Prefix},
}, },
{ {
name: "pbkdf2, parse error", name: "pbkdf2, parse error",
@ -277,9 +297,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"Hash": HashModeSHA1, "Hash": HashModeSHA1,
}, },
}, },
Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5}, Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix}, wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix, md5salted.Prefix},
}, },
{ {
name: "pbkdf2, sha224", name: "pbkdf2, sha224",
@ -291,9 +311,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"Hash": HashModeSHA224, "Hash": HashModeSHA224,
}, },
}, },
Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5}, Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix}, wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix, md5salted.Prefix},
}, },
{ {
name: "pbkdf2, sha256", name: "pbkdf2, sha256",
@ -305,9 +325,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"Hash": HashModeSHA256, "Hash": HashModeSHA256,
}, },
}, },
Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5}, Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix}, wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix, md5salted.Prefix},
}, },
{ {
name: "pbkdf2, sha384", name: "pbkdf2, sha384",
@ -319,9 +339,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"Hash": HashModeSHA384, "Hash": HashModeSHA384,
}, },
}, },
Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5}, Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix}, wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix, md5salted.Prefix},
}, },
{ {
name: "pbkdf2, sha512", name: "pbkdf2, sha512",
@ -333,9 +353,9 @@ func TestPasswordHashConfig_PasswordHasher(t *testing.T) {
"Hash": HashModeSHA512, "Hash": HashModeSHA512,
}, },
}, },
Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5}, Verifiers: []HashName{HashNameArgon2, HashNameBcrypt, HashNameMd5, HashNameMd5Plain, HashNameMd5Salted},
}, },
wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix}, wantPrefixes: []string{pbkdf2.Prefix, argon2.Prefix, bcrypt.Prefix, md5.Prefix, md5salted.Prefix},
}, },
} }
for _, tt := range tests { for _, tt := range tests {