Python hashing password with pbkdf2

Issue

I have the snippet of code implemented on GoLang that works fine

package main

import (
    "crypto/sha256"
    "encoding/hex"
    "fmt"

    "golang.org/x/crypto/pbkdf2"
)

func main() {
    newPasswd := pbkdf2.Key([]byte("test"), []byte("Gare5vgHIo"), 10000, 50, sha256.New)
    fmt.Println(hex.EncodeToString(newPasswd), nil)
}

I am trying to do the same on Python

def main():

    password = b'test'
    salt = b'Gare5vgHIo'
    iterations = 1000

    key = pbkdf2_hmac("sha256", password, salt, iterations, 50)

    print(key)
    print(key.decode())

But key.decode() method throws an error:

UnicodeDecodeError('utf-8', b'\xd9\xb2;\x0f$\x9a\x9c\t\x91\x16\x81\xb8a\x00\xd8\xdd{e.\xa9\x7f\xe9\x92dH\xa6\x05\x16\xd8\xbb\xfdy\x13\xc5D\x1c\xa2\x93e\xbf{\\\x19\xc1\x8df\xf4\xbft\xe2', 5, 6, 'invalid start byte')

What am I doing wrong for the Python code?

Solution

.decode() is trying to convert from bytes to str by interpreting the bytes as UTF-8 encoded data (you can pass it an argument to use a different codec, but it’s fundamentally intended for converting encoded representations of text data back to str, and random raw bytes are not an encoded representation of text). UTF-8 is a self-checking encoding; random bytes rarely pass the self-checks.

If you want to display the bytes as a hexadecimal string, use:

print(key.hex())

where bytes.hex is a bytes method that converts directly to a str of twice the length, representing each byte as two hexadecimal characters.

On very old (pre-3.5) version of Python, bytes does not have a .hex() method, so you’d import the binascii module and do:

print(binascii.hexlify(hey))

but that’s not necessary on any currently supported version of Python.

Answered By – ShadowRanger

Answer Checked By – Candace Johnson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.