Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow importing salted sha hashing algorithms #2741

Merged
merged 37 commits into from
Jan 28, 2023
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
ea26fed
add ssha, ssha256, and ssha512 hashing algorithms
zambien Sep 16, 2022
e6153a3
working on adding ssha tests to identity
zambien Sep 16, 2022
ab49015
tests passing
zambien Sep 16, 2022
6bac8cf
remove accidental duplicate lowercase TestHandler files for SSHA
zambien Sep 16, 2022
c908d20
Merge branch 'master' into ssha_algs
zambien Sep 16, 2022
2f4047c
return the same error message when passwords do not match
zambien Sep 19, 2022
2538556
Merge branch 'ssha_algs' of github.com:zambien/kratos into ssha_algs
zambien Sep 19, 2022
f87bbec
pull latest pwscheme master
zambien Sep 23, 2022
9639dff
demo(serlo-hash): hacky code for dealing with sha1 salt + pass
hugotiburtino Oct 27, 2022
7dfb1a4
feat: add more general sha1 implementation
elbotho Oct 27, 2022
d8140b9
add tests, revert to hex hack
elbotho Oct 27, 2022
c519b84
without hex lib
elbotho Oct 27, 2022
16a76fb
add more tests
elbotho Oct 27, 2022
2d72ae0
generalise sha, replace pwsheme lib
elbotho Oct 28, 2022
7cef479
add sha256 and sha512
elbotho Oct 28, 2022
fbf077a
sha: update tests
elbotho Oct 28, 2022
eb0205a
cleanup
elbotho Oct 28, 2022
9295197
Minor style change
hugotiburtino Oct 28, 2022
5a8c943
Merge pull request #1 from serlo/ssha_sha
hugotiburtino Oct 28, 2022
63e2790
Merge pull request #2 from serlo/ssha_algs
zambien Oct 29, 2022
04495a3
Merge remote-tracking branch 'origin/master' int ssha_algs
hugotiburtino Oct 30, 2022
1d259ad
test(hash): add test for not existent sha type
hugotiburtino Oct 30, 2022
4f91739
refactor(hash): simplify regex for sha
hugotiburtino Oct 30, 2022
f1103d3
style(hash): put decodeFirebaseScryptHash before sha since it was
hugotiburtino Oct 30, 2022
4e86499
refactor(hash): abstract SSHA comparators
hugotiburtino Oct 30, 2022
4b0db1e
refactor(hash): reduce SSHA regex and handling to just one
hugotiburtino Oct 30, 2022
71b4d60
refactor(hash): avoid unecessary double converting and minor renaming
hugotiburtino Oct 30, 2022
787fbbe
style(hasher): put tests for firescrypt after the ones for scrypt
hugotiburtino Oct 30, 2022
07dce17
Merge pull request #3 from serlo/ssha_algs
zambien Oct 31, 2022
f0ef517
Revert "Refactor SSHA and SHA comparators"
zambien Oct 31, 2022
33332d8
Merge pull request #4 from zambien/revert-3-ssha_algs
zambien Oct 31, 2022
7f0e826
refactor(hash): abstract SSHA comparator and minor improvements
hugotiburtino Nov 1, 2022
c6b3a6e
Merge pull request #5 from serlo/ssha_algs
zambien Nov 5, 2022
fea0bbd
fix: bug in parser error handling
hperl Nov 21, 2022
3a18248
chore: guard against unknown SHA hashes
hperl Jan 27, 2023
95aa572
Merge remote-tracking branch 'origin/master' into ssha_algs
hperl Jan 27, 2023
de64823
chore: fix linter warnings
hperl Jan 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 6 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ replace (

// Use the internal httpclient which can be generated in this codebase but mark it as the
// official SDK, allowing for the Ory CLI to consume Ory Kratos' CLI commands.
go.mongodb.org/mongo-driver => go.mongodb.org/mongo-driver v1.4.6
golang.org/x/sys => golang.org/x/sys v0.0.0-20220319134239-a9b59b0215f8
gopkg.in/DataDog/dd-trace-go.v1 => gopkg.in/DataDog/dd-trace-go.v1 v1.27.1-0.20201005154917-54b73b3e126a
)

Expand Down Expand Up @@ -99,9 +97,9 @@ require (
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.36.4
go.opentelemetry.io/otel v1.11.1
go.opentelemetry.io/otel/trace v1.11.1
golang.org/x/crypto v0.1.0
golang.org/x/net v0.3.0
golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783
golang.org/x/crypto v0.5.0
golang.org/x/net v0.5.0
golang.org/x/oauth2 v0.4.0
golang.org/x/sync v0.1.0
golang.org/x/tools v0.4.0
)
Expand Down Expand Up @@ -170,7 +168,6 @@ require (
github.com/go-playground/locales v0.13.0 // indirect
github.com/go-playground/universal-translator v0.17.0 // indirect
github.com/go-sql-driver/mysql v1.7.0 // indirect
github.com/go-stack/stack v1.8.1 // indirect
github.com/gobuffalo/envy v1.10.2 // indirect
github.com/gobuffalo/flect v0.3.0 // indirect
github.com/gobuffalo/github_flavored_markdown v1.1.3 // indirect
Expand Down Expand Up @@ -319,9 +316,9 @@ require (
go.uber.org/zap v1.17.0 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/mod v0.7.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/term v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
golang.org/x/sys v0.4.0 // indirect
golang.org/x/term v0.4.0 // indirect
golang.org/x/text v0.6.0 // indirect
golang.org/x/time v0.1.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect
Expand Down
169 changes: 150 additions & 19 deletions go.sum

Large diffs are not rendered by default.

191 changes: 165 additions & 26 deletions hash/hash_comparator.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import (
"crypto/aes"
"crypto/cipher"
"crypto/md5" // #nosec G501
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/subtle"
"encoding/base64"
"fmt"
Expand Down Expand Up @@ -37,6 +40,10 @@ func Compare(ctx context.Context, password []byte, hash []byte) error {
return ComparePbkdf2(ctx, password, hash)
case IsScryptHash(hash):
return CompareScrypt(ctx, password, hash)
case IsSSHAHash(hash):
return CompareSSHA(ctx, password, hash)
case IsSHAHash(hash):
return CompareSHA(ctx, password, hash)
case IsFirebaseScryptHash(hash):
return CompareFirebaseScrypt(ctx, password, hash)
case IsMD5Hash(hash):
Expand Down Expand Up @@ -142,6 +149,31 @@ func CompareScrypt(_ context.Context, password []byte, hash []byte) error {
return errors.WithStack(ErrMismatchedHashAndPassword)
}

func CompareSSHA(_ context.Context, password []byte, hash []byte) error {
hasher, salt, hash, err := decodeSSHAHash(string(hash))

if err != nil {
return err
}

raw := append(password[:], salt[:]...)

return compareSHAHelper(hasher, raw, hash)
}

func CompareSHA(_ context.Context, password []byte, hash []byte) error {

hasher, pf, salt, hash, err := decodeSHAHash(string(hash))
if err != nil {
return err
}

r := strings.NewReplacer("{SALT}", string(salt), "{PASSWORD}", string(password))
raw := []byte(r.Replace(string(pf)))

return compareSHAHelper(hasher, raw, hash)
}

func CompareFirebaseScrypt(_ context.Context, password []byte, hash []byte) error {
// Extract the parameters, salt and derived key from the encoded password
// hash.
Expand Down Expand Up @@ -206,36 +238,36 @@ var (
isArgon2iHash = regexp.MustCompile(`^\$argon2i\$`)
isPbkdf2Hash = regexp.MustCompile(`^\$pbkdf2-sha[0-9]{1,3}\$`)
isScryptHash = regexp.MustCompile(`^\$scrypt\$`)
isSSHAHash = regexp.MustCompile(`^{SSHA(256|512)?}.*`)
isSHAHash = regexp.MustCompile(`^\$sha(1|256|512)\$`)
isFirebaseScryptHash = regexp.MustCompile(`^\$firescrypt\$`)
isMD5Hash = regexp.MustCompile(`^\$md5\$`)
)

func IsBcryptHash(hash []byte) bool {
return isBcryptHash.Match(hash)
}

func IsArgon2idHash(hash []byte) bool {
return isArgon2idHash.Match(hash)
}

func IsArgon2iHash(hash []byte) bool {
return isArgon2iHash.Match(hash)
}

func IsPbkdf2Hash(hash []byte) bool {
return isPbkdf2Hash.Match(hash)
}

func IsScryptHash(hash []byte) bool {
return isScryptHash.Match(hash)
}

func IsFirebaseScryptHash(hash []byte) bool {
return isFirebaseScryptHash.Match(hash)
}

func IsMD5Hash(hash []byte) bool {
return isMD5Hash.Match(hash)
func IsBcryptHash(hash []byte) bool { return isBcryptHash.Match(hash) }
func IsArgon2idHash(hash []byte) bool { return isArgon2idHash.Match(hash) }
func IsArgon2iHash(hash []byte) bool { return isArgon2iHash.Match(hash) }
func IsPbkdf2Hash(hash []byte) bool { return isPbkdf2Hash.Match(hash) }
func IsScryptHash(hash []byte) bool { return isScryptHash.Match(hash) }
func IsSSHAHash(hash []byte) bool { return isSSHAHash.Match(hash) }
func IsSHAHash(hash []byte) bool { return isSHAHash.Match(hash) }
func IsFirebaseScryptHash(hash []byte) bool { return isFirebaseScryptHash.Match(hash) }
func IsMD5Hash(hash []byte) bool { return isMD5Hash.Match(hash) }

func IsValidHashFormat(hash []byte) bool {
if IsBcryptHash(hash) ||
IsArgon2idHash(hash) ||
IsArgon2iHash(hash) ||
IsPbkdf2Hash(hash) ||
IsScryptHash(hash) ||
IsSSHAHash(hash) ||
IsSHAHash(hash) ||
IsFirebaseScryptHash(hash) ||
IsMD5Hash(hash) {
return true
} else {
return false
}
}

func decodeArgon2idHash(encodedHash string) (p *config.Argon2, salt, hash []byte, err error) {
Expand Down Expand Up @@ -339,6 +371,113 @@ func decodeScryptHash(encodedHash string) (p *Scrypt, salt, hash []byte, err err
return p, salt, hash, nil
}

// decodeSHAHash decodes SHA[1|256|512] encoded password hash in custom PHC format.
// format: $sha1$pf=<salting-format>$<salt>$<hash>
func decodeSHAHash(encodedHash string) (hasher string, pf, salt, hash []byte, err error) {
parts := strings.Split(encodedHash, "$")

if len(parts) != 5 {
return "", nil, nil, nil, ErrInvalidHash
}

hasher = parts[1]

_, err = fmt.Sscanf(parts[2], "pf=%s", &pf)
if err != nil {
return "", nil, nil, nil, err
}

pf, err = base64.StdEncoding.Strict().DecodeString(string(pf))
if err != nil {
return "", nil, nil, nil, err
}

salt, err = base64.StdEncoding.Strict().DecodeString(parts[3])
if err != nil {
return "", nil, nil, nil, err
}

hash, err = base64.StdEncoding.Strict().DecodeString(parts[4])
if err != nil {
return "", nil, nil, nil, err
}

return hasher, pf, salt, hash, nil
}

// used for CompareSHA and CompareSSHA
func compareSHAHelper(hasher string, raw []byte, hash []byte) error {

var sha []byte

switch hasher {
case "sha1":
sum := sha1.Sum(raw)
sha = sum[:]
case "sha256":
sum := sha256.Sum256(raw)
sha = sum[:]
case "sha512":
sum := sha512.Sum512(raw)
sha = sum[:]
default:
return errors.WithStack(ErrMismatchedHashAndPassword)
}

encodedHash := []byte(base64.StdEncoding.EncodeToString(hash))
newEncodedHash := []byte(base64.StdEncoding.EncodeToString(sha))

// Check that the contents of the hashed passwords are identical.
// subtle.ConstantTimeCompare() is used to help prevent timing attacks.
if subtle.ConstantTimeCompare(encodedHash, newEncodedHash) == 1 {
return nil
}
return errors.WithStack(ErrMismatchedHashAndPassword)
}

// decodeSSHAHash decodes SSHA[1|256|512] encoded password hash in usual {SSHA...} format.
func decodeSSHAHash(encodedHash string) (hasher string, salt, hash []byte, err error) {
re := regexp.MustCompile(`\{([^}]*)\}`)
match := re.FindStringSubmatch(string(encodedHash))

var index_of_salt_begin int
var index_of_hash_begin int

switch match[1] {
case "SSHA":
hasher = "sha1"
index_of_hash_begin = 6
index_of_salt_begin = 20

case "SSHA256":
hasher = "sha256"
index_of_hash_begin = 9
index_of_salt_begin = 32

case "SSHA512":
hasher = "sha512"
index_of_hash_begin = 9
index_of_salt_begin = 64

default:
return "", nil, nil, ErrInvalidHash
}

decoded, err := base64.StdEncoding.DecodeString(string(encodedHash[index_of_hash_begin:]))
if err != nil {
return "", nil, nil, ErrInvalidHash
}

if len(decoded) < index_of_salt_begin+1 {
return "", nil, nil, ErrInvalidHash
}

salt = decoded[index_of_salt_begin:]
hash = decoded[:index_of_salt_begin]

return hasher, salt, hash, nil
}

// decodeFirebaseScryptHash decodes Firebase Scrypt encoded password hash.
// format: $firescrypt$ln=<mem_cost>,r=<rounds>,p=<parallelization>$<salt>$<hash>$<salt_separator>$<signer_key>
func decodeFirebaseScryptHash(encodedHash string) (p *Scrypt, salt, saltSeparator, hash, signerKey []byte, err error) {
Expand Down
50 changes: 50 additions & 0 deletions hash/hasher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,56 @@ func TestCompare(t *testing.T) {
assert.Error(t, hash.Compare(context.Background(), []byte("tesu"), []byte("$scrypt$ln=16384,r=8,p=1$2npRo7P03Mt8keSoMbyD/tKFWyUzjiQf2svUaNDSrhA=$MiCzNcIplSMqSBrm4HckjYqYhaVPPjTARTzwB1cVNYE=")))
assert.Error(t, hash.Compare(context.Background(), []byte("tesu"), []byte("$scrypt$ln=abc,r=8,p=1$2npRo7P03Mt8keSoMbyD/tKFWyUzjiQf2svUaNDSrhA=$MiCzNcIplSMqSBrm4HckjYqYhaVPPjTARTzwB1cVNYE=")))

assert.Nil(t, hash.Compare(context.Background(), []byte("test123"), []byte("{SSHA}JFZFs0oHzxbMwkSJmYVeI8MnTDy/276a")))
assert.Nil(t, hash.CompareSSHA(context.Background(), []byte("test123"), []byte("{SSHA}JFZFs0oHzxbMwkSJmYVeI8MnTDy/276a")))
assert.Error(t, hash.CompareSSHA(context.Background(), []byte("badtest"), []byte("{SSHA}JFZFs0oHzxbMwkSJmYVeI8MnTDy/276a")))
assert.Error(t, hash.Compare(context.Background(), []byte(""), []byte("{SSHA}tooshort")))

assert.Nil(t, hash.Compare(context.Background(), []byte("test123"), []byte("{SSHA256}czO44OTV17PcF1cRxWrLZLy9xHd7CWyVYplr1rOhuMlx/7IK")))
assert.Nil(t, hash.CompareSSHA(context.Background(), []byte("test123"), []byte("{SSHA256}czO44OTV17PcF1cRxWrLZLy9xHd7CWyVYplr1rOhuMlx/7IK")))
assert.Error(t, hash.CompareSSHA(context.Background(), []byte("badtest"), []byte("{SSHA256}czO44OTV17PcF1cRxWrLZLy9xHd7CWyVYplr1rOhuMlx/7IK")))

assert.Nil(t, hash.Compare(context.Background(), []byte("test123"), []byte("{SSHA512}xPUl/px+1cG55rUH4rzcwxdOIPSB2TingLpiJJumN2xyDWN4Ix1WQG3ihnvHaWUE8MYNkvMi5rf0C9NYixHsE6Yh59M=")))
assert.Nil(t, hash.CompareSSHA(context.Background(), []byte("test123"), []byte("{SSHA512}xPUl/px+1cG55rUH4rzcwxdOIPSB2TingLpiJJumN2xyDWN4Ix1WQG3ihnvHaWUE8MYNkvMi5rf0C9NYixHsE6Yh59M=")))
assert.Error(t, hash.CompareSSHA(context.Background(), []byte("badtest"), []byte("{SSHA512}xPUl/px+1cG55rUH4rzcwxdOIPSB2TingLpiJJumN2xyDWN4Ix1WQG3ihnvHaWUE8MYNkvMi5rf0C9NYixHsE6Yh59M=")))
assert.Error(t, hash.CompareSSHA(context.Background(), []byte("test123"), []byte("{SSHAnotExistent}xPUl/px+1cG55rUH4rzcwxdOIPSB2TingLpiJJumN2xyDWN4Ix1WQG3ihnvHaWUE8MYNkvMi5rf0C9NYixHsE6Yh59M=")))

//pf: {SALT}{PASSWORD}
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$2qU2SGWP8viTM1md3FiI3+rjWXQ=")))
assert.Error(t, hash.Compare(context.Background(), []byte("wrongpass"), []byte("$sha1$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$2qU2SGWP8viTM1md3FiI3+rjWXQ=")))
assert.Error(t, hash.Compare(context.Background(), []byte("tset"), []byte("$sha1$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$2qU2SGWP8viTM1md3FiI3+rjWXQ=")))
// wrong salt
assert.Error(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$pf=e1NBTFR9e1BBU1NXT1JEfQ==$cDJvb3ZrZGJ6cQ==$2qU2SGWP8viTM1md3FiI3+rjWXQ=")))
// salt not encoded
assert.Error(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$pf=e1NBTFR9e1BBU1NXT1JEfQ==$5opmkgz03r$2qU2SGWP8viTM1md3FiI3+rjWXQ=")))
assert.Nil(t, hash.Compare(context.Background(), []byte("BwS^514g^cv@Z"), []byte("$sha1$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$99h9net4BXl7qdTRaiGUobLROxM=")))
// no format string
assert.Error(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$pf=$NW9wbWtnejAzcg==$2qU2SGWP8viTM1md3FiI3+rjWXQ=")))
assert.Error(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$$NW9wbWtnejAzcg==$2qU2SGWP8viTM1md3FiI3+rjWXQ=")))
// wrong number of parameters
assert.Error(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$NW9wbWtnejAzcg==$2qU2SGWP8viTM1md3FiI3+rjWXQ=")))
// pf: ??staticPrefix??{SALT}{PASSWORD}
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$pf=Pz9zdGF0aWNQcmVmaXg/P3tTQUxUfXtQQVNTV09SRH0=$NW9wbWtnejAzcg==$SAAxMUn7jxckQXkBmsVF0nHwqso=")))
// pf: {PASSWORD}%%{SALT}
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$pf=e1BBU1NXT1JEfSUle1NBTFR9$NW9wbWtnejAzcg==$YX0AW8/MW5ojUlnzTaR43ucHCog=")))
// pf: ${PASSWORD}${SALT}$
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha1$pf=JHtQQVNTV09SRH0ke1NBTFR9JA==$NW9wbWtnejAzcg==$iE5n1yjX3oAdxRHwZ4u57I4LpQo=")))

//pf: {SALT}{PASSWORD}
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha256$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$0gfRVLCvtBCk20udLDEY5vNhujWx7RGjwRIS1ebMsLY=")))
assert.Nil(t, hash.CompareSHA(context.Background(), []byte("test"), []byte("$sha256$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$0gfRVLCvtBCk20udLDEY5vNhujWx7RGjwRIS1ebMsLY=")))
assert.Error(t, hash.Compare(context.Background(), []byte("wrongpass"), []byte("$sha256$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$0gfRVLCvtBCk20udLDEY5vNhujWx7RGjwRIS1ebMsLY=")))
//pf: {SALT}$${PASSWORD}
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha256$pf=e1NBTFR9JCR7UEFTU1dPUkR9$NW9wbWtnejAzcg==$HokCOi9OtiZaZRvnkgemV3B4UUHpI7kA8zq/EZWH2NY=")))

//pf: {SALT}{PASSWORD}
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha512$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$6ctpVuApMNp0CgBXcdHw/GC562eFEFGr4gpgANX8ZYsX+j5B19IkdmOY2Fytsz3QUwSWdGcUjbqwgJGTH0UYvw==")))
assert.Nil(t, hash.CompareSHA(context.Background(), []byte("test"), []byte("$sha512$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$6ctpVuApMNp0CgBXcdHw/GC562eFEFGr4gpgANX8ZYsX+j5B19IkdmOY2Fytsz3QUwSWdGcUjbqwgJGTH0UYvw==")))
assert.Error(t, hash.Compare(context.Background(), []byte("wrongpass"), []byte("$sha512$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$6ctpVuApMNp0CgBXcdHw/GC562eFEFGr4gpgANX8ZYsX+j5B19IkdmOY2Fytsz3QUwSWdGcUjbqwgJGTH0UYvw==")))
//pf: {SALT}$${PASSWORD}
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$sha512$pf=e1NBTFR9JCR7UEFTU1dPUkR9$NW9wbWtnejAzcg==$1F9BPW8UtdJkZ9Dhlf+D4X4dJ9xfuH8y04EfuCP2k4aGPPq/aWxU9/xe3LydHmYW1/K3zu3NFO9ETVrZettz3w==")))

assert.Error(t, hash.Compare(context.Background(), []byte("test"), []byte("$shaNotExistent$pf=e1NBTFR9e1BBU1NXT1JEfQ==$NW9wbWtnejAzcg==$6ctpVuApMNp0CgBXcdHw/GC562eFEFGr4gpgANX8ZYsX+j5B19IkdmOY2Fytsz3QUwSWdGcUjbqwgJGTH0UYvw==")))
assert.Nil(t, hash.Compare(context.Background(), []byte("test"), []byte("$md5$CY9rzUYh03PK3k6DJie09g==")))
assert.Nil(t, hash.CompareMD5(context.Background(), []byte("test"), []byte("$md5$CY9rzUYh03PK3k6DJie09g==")))
assert.Error(t, hash.Compare(context.Background(), []byte("test"), []byte("$md5$WhBei51A4TKXgNYuoiZdig==")))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"password": {
"type": "password",
"identifiers": [
"import-5@ory.sh"
"import-hash-6@ory.sh"
],
"config": {
},
Expand All @@ -13,7 +13,7 @@
"schema_id": "default",
"state": "active",
"traits": {
"email": "import-5@ory.sh"
"email": "import-hash-6@ory.sh"
},
"metadata_public": null,
"metadata_admin": null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"password": {
"type": "password",
"identifiers": [
"import-6@ory.sh"
"import-hash-7@ory.sh"
],
"config": {
},
Expand All @@ -13,7 +13,7 @@
"schema_id": "default",
"state": "active",
"traits": {
"email": "import-6@ory.sh"
"email": "import-hash-7@ory.sh"
},
"metadata_public": null,
"metadata_admin": null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"password": {
"type": "password",
"identifiers": [
"import-4@ory.sh"
"import-hash-8@ory.sh"
],
"config": {
},
Expand All @@ -13,7 +13,7 @@
"schema_id": "default",
"state": "active",
"traits": {
"email": "import-4@ory.sh"
"email": "import-hash-8@ory.sh"
},
"metadata_public": null,
"metadata_admin": null
Expand Down
Loading