Skip to content

Commit

Permalink
feat(pbkdf2): added verify function
Browse files Browse the repository at this point in the history
  • Loading branch information
aldy505 committed May 28, 2021
1 parent 5837d07 commit 8bf58a1
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 5 deletions.
51 changes: 51 additions & 0 deletions pbkdf2/pbkdf2.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@ import (
"crypto/sha1"
"crypto/sha256"
"crypto/sha512"
"crypto/subtle"
"encoding/hex"
"errors"
"io"
"strconv"
"strings"

"github.com/aldy505/phc-crypto/format"
"golang.org/x/crypto/pbkdf2"
Expand Down Expand Up @@ -63,5 +66,53 @@ func Hash(plain string, config Config) (string, error) {
})

return hashString, nil
}

func Verify(hash string, plain string) (bool, error) {
deserialize := format.Deserialize(hash)

if !strings.HasPrefix(deserialize.ID, "pbkdf2") {
return false, errors.New("hashed string is not pbkdf2 instance")
}

decodedHash, err := hex.DecodeString(deserialize.Hash)
if err != nil {
return false, err
}
keyLen := int(len(decodedHash))

rounds, err := strconv.ParseInt(deserialize.Params["i"].(string), 10, 32)
if err != nil {
return false, err
}

salt, err := hex.DecodeString(deserialize.Salt)
if err != nil {
return false, err
}

hashFunc := strings.Replace(deserialize.ID, "pbkdf2", "", 1)

var verifyHash []byte

if hashFunc == "sha1" {
verifyHash = pbkdf2.Key([]byte(plain), salt, int(rounds), keyLen, sha1.New)
} else if hashFunc == "sha256" {
verifyHash = pbkdf2.Key([]byte(plain), salt, int(rounds), keyLen, sha256.New)
} else if hashFunc == "sha224" {
verifyHash = pbkdf2.Key([]byte(plain), salt, int(rounds), keyLen, sha256.New224)
} else if hashFunc == "sha512" {
verifyHash = pbkdf2.Key([]byte(plain), salt, int(rounds), keyLen, sha512.New)
} else if hashFunc == "sha384" {
verifyHash = pbkdf2.Key([]byte(plain), salt, int(rounds), keyLen, sha512.New384)
} else if hashFunc == "md5" {
verifyHash = pbkdf2.Key([]byte(plain), salt, int(rounds), keyLen, md5.New)
} else {
return false, errors.New("we don't support " + hashFunc + " for a hash function.")
}

if subtle.ConstantTimeCompare(decodedHash, verifyHash) == 1 {
return true, nil
}
return false, nil
}
3 changes: 3 additions & 0 deletions phc-crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,9 @@ func (a *Algo) Verify(hash, plain string) (verify bool, err error) {
} else if a.Name == "argon2" {
verify, err = argon2.Verify(hash, plain)
return
} else if a.Name == "pbkdf2" {
verify, err = pbkdf2.Verify(hash, plain)
return
}
verify = false
err = errors.New("the algorithm provided is not (yet) supported")
Expand Down
47 changes: 42 additions & 5 deletions phc-crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ func TestPHCCrypto(t *testing.T) {
if err != nil {
t.Error(err)
}
t.Log(hash)
typeof := reflect.TypeOf(hash).Kind()
if typeof != reflect.String {
t.Error("returned type is not string")
Expand Down Expand Up @@ -97,7 +96,6 @@ func TestPHCCrypto(t *testing.T) {
if err != nil {
t.Error(err)
}
t.Log(hash)
typeof := reflect.TypeOf(hash).Kind()
if typeof != reflect.String {
t.Error("returned type is not string")
Expand All @@ -109,7 +107,6 @@ func TestPHCCrypto(t *testing.T) {
t.Error(err)
}
hash, err := crypto.Hash("password123")
t.Log(hash)
if err != nil {
t.Error(err)
}
Expand Down Expand Up @@ -157,7 +154,6 @@ func TestPHCCrypto(t *testing.T) {
if err != nil {
t.Error(err)
}
t.Log(hash)
typeof := reflect.TypeOf(hash).Kind()
if typeof != reflect.String {
t.Error("returned type is not string")
Expand Down Expand Up @@ -216,11 +212,52 @@ func TestPHCCrypto(t *testing.T) {
if err != nil {
t.Error(err)
}
t.Log(hash)
typeof := reflect.TypeOf(hash).Kind()
if typeof != reflect.String {
t.Error("returned type is not string")
}
})
t.Run("verify should return true", func(t *testing.T) {
crypto, err := phccrypto.Use("pbkdf2", phccrypto.Config{})
if err != nil {
t.Error(err)
}
hash, err := crypto.Hash("password123")
if err != nil {
t.Error(err)
}
verify, err := crypto.Verify(hash, "password123")
if err != nil {
t.Error(err)
}
typeof := reflect.TypeOf(verify).Kind()
if typeof != reflect.Bool {
t.Error("returned type is not boolean")
}
if !verify {
t.Error("verify function returned false")
}
})
t.Run("verify should return false", func(t *testing.T) {
crypto, err := phccrypto.Use("pbkdf2", phccrypto.Config{})
if err != nil {
t.Error(err)
}
hash, err := crypto.Hash("password123")
if err != nil {
t.Error(err)
}
verify, err := crypto.Verify(hash, "password321")
if err != nil {
t.Error(err)
}
typeof := reflect.TypeOf(verify).Kind()
if typeof != reflect.Bool {
t.Error("returned type is not boolean")
}
if verify {
t.Error("verify function returned false")
}
})
})
}

0 comments on commit 8bf58a1

Please sign in to comment.