Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

austenc's avatar

Checking for a hashed value in a query?

Is it possible to use Hash::make() and still query for that specific hashed value?

For example, if I was using sha1(), it would be something like:

$search = 'someValue';
$query->where('table.hash_value', '=', sha1($search));   

How could I use Hash to do something like this? I know about Hash::check() but don't think that works in this instance.

0 likes
16 replies
bart's avatar

Why didn't you try this:

$password = Hash::make('plaintext');
$result = Model::wherePassword($password)->first();
1 like
austenc's avatar

@bart because Hash::make() will return a different hash each time?

bart's avatar

That's true, sorry about that. Why couldn't you use the Hash:check() method?

austenc's avatar

I need to be able to query by this value, so Hash::check doesn't work since it returns a boolean... seems my only option is to use another (less secure than bcrypt) method of hashing?

bart's avatar
bart
Best Answer
Level 13

It's in the nature of the algorithm itself. You can't search for a salted hash - that's the idea behind it. Different hashes will be generated with the same input. So the answer is: You have to use another hashing algorithm which always returns the same output. And last but not least is less secure.

Maybe you can tell us something about your intention. Why do you wanna do such an unusual query?

1 like
austenc's avatar

@bart I am storing sensitive personal information (government issued ID # in this case) and need administrators to have the ability to search by (and edit) such information. I've been storing an encrypted value, but when searching tons of records also storing a hash makes sense. Thanks for the explanation about bcrypt, I wasn't realizing it was like that always.

@bashy thank you for the link, looking at the Hashing class provides some nice insights as to the PHP behind it. I looked around the code for the Auth::attempt() method as well and it appears that the record is found given the other (non-password) credentials, and then the Hash::check() method is called separately... so it's still not part of the query. After learning the nature of bcrypt, that certainly makes sense. It's unfortunately looking like I'll need to salt+hash using another more insecure algorithm to achieve what I want in this case.

bashy's avatar

Indeed, I didn't look too far into it but this is interesting

/**
  * Check the given plain value against a hash.
  *
  * @param string $value
  * @param string $hashedValue
  * @param array $options
  * @return bool
  */
public function check($value, $hashedValue, array $options = array())
{
    return password_verify($value, $hashedValue);
}
pmall's avatar

There is no way of defining the bcrypt salt somewhere ? It would still be secure because nobody should know which salt you are using but it would generate constant hashes.

austenc's avatar

@developeritsme this is a pretty old thread. I looked at using the encryption library, but that would not have been very efficient query-wise. You'd have to query all the rows and then filter (decrypt) them. What I ended up doing is storing both an encrypted version of the value, and a hashed version of the value + salt string that I put in config which is the same every time. Now I can allow efficient searches for this value (just a simple WHERE clause) and have access to the decrypted version for edits once I've got that row's id.

1 like
pmall's avatar

Holy sh** that was a eight months bump

Please or to participate in this conversation.