Match bcrypt hash with plaintext I have a bcrypt hash: $2b$10$kn7yEh2nYiDqDYNY.hjiZOtASBKT9uO4KozbFWDW2XLYnW58nkpq and a list with given plaintext passwords. How can I get the password from the list?
Is $2b$10$kn7yEh2nYiDqDYNY the salt?
TOMATCH=&quot;$2b$10$kn7yEh2nYiDqDYNY.hjiZOtASBKT9uO4KozbFWDW2XLYnW58nkpq"
SALT=b"$2b$10$kn7yEh2nYiDqDYNY.&quot;

for word in words:
    hash = bcrypt.hashpw(word.encode('UTF-8'), SALT)
    
    if TOMATCH == hash:
        print(word)
        break

However, with this I get ValueError: Invalid salt. What am I doing wrong here?
The bcrypt hash value consists of the following parts:

$2b — this indicates that the hash is generated according to the OpenBSD implementation of bcrypt.

10$ — this is the &quot;cost&quot; parameter, indicating that the password is hashed with 210 (i.e. 1024) iterations of the blowfish cipher. A higher cost parameter results in password hashes that are harder to crack by brute force.

kn7yEh2nYiDqDYNY.hjiZO — This is the 128-bit salt value, encoded in base64 as 22 ASCII characters

The remaining characters correspond to the 184-bit blowfish hash value, encoded in base64 as 31 characters.


If you check the length of your string, I think you'll find that it's actually one character short, which would explain why you're getting error messages. If this character is simply missing, you could always try appending every possible character from 0-9, A-Z, a-z, . and /. One of them ought to work.
Incidentally, I think it would make more sense to use the checkpw() function in the bcrypt module instead of trying to extract the salt yourself. Here's some code that can check every possible last character. It will take a long time to run if the word list is large.
def check_partial_hash(h, words):
    import string
    for last_char in list(string.digits + string.ascii_letters + '/.'):
        hash = h + last_char
        for word in words:
            if bcrypt.checkpw(word.encode('UTF-8'), hash.encode('UTF-8')):
                return (word, hash)
    return None

partial_hash = u'$2b$10$kn7yEh2nYiDqDYNY.hjiZOtASBKT9uO4KozbFWDW2XLYnW58nkpq'
word_list = [ u'foo', u'bar', u'asd', u'baz' ]
check_partial_hash(partial_hash, word_list)