scalagopbkdf2

How to simulate password hash of pbkdf2-scala in Golang pbkdf2


Our app uses the library, SecureHash object, in order to create one-way password: https://github.com/nremond/pbkdf2-scala/blob/master/src/main/scala/io/github/nremond/SecureHash.scala

Now my problem is that my code in Go returns -1 for password check.

package main

import (
    "bytes"
    "crypto/rand"
    "crypto/sha512"
    "fmt"
    "golang.org/x/crypto/pbkdf2"
    "math/big"
    "strings"
)

func main() {
    iteration := 25000

    // Hash User input
    password := []byte("123")
    salt := "yCyQMMMBt1TuPa1F9FeKfT0yrNIF8tLB"
    key := pbkdf2.Key(password, []byte(salt), iteration, sha512.Size, sha512.New)

    // COMPARE PASSWORD fetched from DB
        // 123 hash in scala
    tokenS := strings.Split("$pbkdf2-sha512$25000$yCyQMMMBt1TuPa1F9FeKfT0yrNIF8tLB$TtQt5BZLs4qlA0YAkcGukZwu7pkxOLcxwuoQB3qNtxM", "$")
    passwordHashInDatabase := tokenS[4]
    out := bytes.Compare(key, []byte(passwordHashInDatabase))
    fmt.Println("out: ", out)
}

Solution

  • You have a couple problems:

    Here's a hastily fixed implemnentation:

    package main
    
    import (
        "bytes"
        "crypto/sha512"
        "encoding/base64"
        "fmt"
        "log"
        "strings"
    
        "golang.org/x/crypto/pbkdf2"
    )
    
    func b64Decode(s string) ([]byte, error) {
        s = strings.ReplaceAll(s, ".", "+")
        return base64.RawStdEncoding.DecodeString(s)
    }
    
    func main() {
        iteration := 25000
    
        // Hash User input
        password := []byte("123")
        salt, err := b64Decode("yCyQMMMBt1TuPa1F9FeKfT0yrNIF8tLB")
        if err != nil {
            log.Fatal("Failed to base64 decode the salt: %s", err)
        }
        key := pbkdf2.Key(password, salt, iteration, 32, sha512.New)
    
        // COMPARE PASSWORD fetched from DB
        // 123 hash in scala
        tokens := strings.Split("$pbkdf2-sha512$25000$yCyQMMMBt1TuPa1F9FeKfT0yrNIF8tLB$TtQt5BZLs4qlA0YAkcGukZwu7pkxOLcxwuoQB3qNtxM", "$")
        passwordHashInDatabase, err := b64Decode(tokens[4])
        if err != nil {
            log.Fatal("Failed to base64 decode password hash from the database: %s", err)
        }
        fmt.Printf("%x\n%x\n", key, passwordHashInDatabase)
        fmt.Printf("%d\n%d\n", len(key), len(passwordHashInDatabase))
        out := bytes.Compare(key, passwordHashInDatabase)
        fmt.Println("out: ", out)
    }
    

    Output:

    4ed42de4164bb38aa503460091c1ae919c2eee993138b731c2ea10077a8db713
    4ed42de4164bb38aa503460091c1ae919c2eee993138b731c2ea10077a8db713
    32
    32
    out:  0
    

    Go Playground