Compare BCrypt hash to Bcrypt hash PHP - php

here's what I'm up against.
I have an app for iPhone that I am building that communicates with password protected pages on my site. The app can get through the password protection fine and can get the response from the page just fine. The problem is that when I try to login to the site from my app it gets rejected. I believe this is because I am hashing the password with Bcrypt in the app before sending it to the site and then checking it with password_verify(), which of course takes the plain text of the password and then the hashed version, but I am giving it two hashed versions of the same thing which it is not accepting.
My question is this: is it possible to compare the two encrypted passwords using password_verify or some other function, or not? And if not, is it secure enough to (dare I say it) send the password in plain text from the app?
Thanks to everyone in advance!

is it possible to compare the two encrypted passwords using password_verify or some other function, or not?
No. password_verify requires the plaintext password and the previously hashed form of the password with the embedded salt as its inputs and there's no way around that. The algorithm is such that you need the salt again to produce the same hash, so your only other option would be to transfer the hash/salt to the client to reproduce the algorithm there. But that's pointless, since you want to do the password confirmation at the server, not on the untrustworthy client.
And if not, is it secure enough to (dare I say it) send the password in plain text from the app?
Sure, as long as the communication channel is secure, meaning you have an SSL connection.

Related

CodeIgniter encryption library issue [duplicate]

I use codeigniter a lot, however I am not really understanding why when I use the encryption library in version 3 the encryption string never comes out the same, even using the same salt/key.
So I have stored a user password as an encrypted string, which uses their own key to encrypt. The key is stored in the database. But when they come to login, and i want to encrypt the entered password to check the strings match, they never do match!
It seems the library always spits out different encrypted strings, no matter if the key is the same or not, how is this going to be useful if I can't match the stored encrypted password to the password they enter at login?
For example, password is 12456 with key a0956f251b9d957071005a2d11e4630a
SAVED PASSWORD IS: 0e6effa48949d6bf19e84530bc86e9a1407086b3b88fc368b6f8b7b53304b313eeebdb695c9cca10b3e7072f608bf4137e7fcc7d24fed54df2b6dcba3f94dcb6Tm05Qmay9G8JuUXps6UstWebmBmJ71BcIPgrW78OvSY=
PASSWORD GENERATED FROM USER LOGIN
6b893dac92155bc663b126b805c7189214ac4667b226f0c6fc22cf0c6bcca5e897c49961e8852ade1c3e85cbecab89df76ea7891727af6bf0bcc232b75d0d441LLUMZgOy4zLwAypuVQuK0lKTXrlXYptKpVdByytH2D8=
935c8f564c4a5ecb53510faa835eca8622069c34d534df6b9c2ea52de2d9bea5976128f6ff83a572ac677be4ebd690bc18e488518c2eed8b1b40a16c9e61d6b2hbKJ6B1VDuLPCXBeDDFzvrlSBIYCtN19M6dQGZRCvUE=
b8e020c7c10d564cfc3a9cc4d50b85ea3422422b73a2dd79930ead1fb601493279ba97645584d6dfa188e62f5eba5dc66d0dafdb7a82c08bf847bc84fc0718daSOVRrDlFmVMB/12ok9kR68ekXJcJvw0yfo/cnU9ojtI=
see they are different every time I try to encrypt the user input? It's not making any sense.
Likewise, if I try to decode the password in the database, with the same key it was encrypted with, I get nothing back, no decrypted password.
So, does anyone know what is going on here?
Randomized encryption is a security property necessary to achieve semantic security. If the encryption would not be randomized then an attacker might detect whether (prefixes of) messages were previously sent only by observing the ciphertexts. You generally don't want the attacker to know anything about the plaintexts except the length.
An encryption function has always a corresponding decryption function. It seems that you're only using one way of the two functions. You should never encrypt your user's passwords. You need to use hashing instead with some strong ones being PBKDF2, bcrypt, scrypt and Argon2. Since hash functions are one-way function, you won't be able to "decrypt" the hashes. In order to authenticate your user, you can run the password through the hash function again in order to compare with the hash that is stored in the database. See more: How to securely hash passwords?
Codigniter documentation:
DO NOT use this or any other encryption library for user password
storage! Passwords must be hashed instead, and you should do that via
PHP’s own Password Hashing extension.
http://www.codeigniter.com/userguide3/libraries/encryption.html
Fully explained here:
http://php.net/manual/en/faq.passwords.php
Try the md5 encryption its good and best till now.
In controller before send password like this:
md5($this->input->post('password));
or use hash() or SHA256/SHA512 they do it well.
It will do the trick.
Enjoy!

Verify password that is hashed outside our control?

Implementing a service that posts a user's ID and an MDG-hashed password to my server for verification.
We store hashes passwords that are generated using the password_hash() function in PHP >5.5.
Is there any way to verify the MD5 hash and our hash point to the same password?
Normally, a password would be submitted to us via a login form and we would verify with password_verify() but without the password in plain text I'm at a bit of a loss.
Normally, a password would be submitted to us via a login form and we
would verify with password_verify() but without the password in plain
text I'm at a bit of a loss.
As long as you use secure transport (SSL), this won't be an issue. That's the standard way that this is done. Otherwise you'll need to implement the hashing mechanism used by password_hash() in your client. Doing this wouldn't make your security scheme any better. It's still susceptible to replay attacks.
Also, you should stay away from MD5 because it's broken.
You can't decrypt it. But if you can change the mechanism for generating the password, you can refer to this post

posting plain-text password, are there other options

Im dealing with legacy code here.
There's a HTML form with username/password inputs.
The form is then sent to the server (using SSL), and the password is compared to the database value.
Question: is there a way to "hide"(encrypt) the password while it is sent to the server?
Even if I'm storing the hashed-password and unique user-salt in the database,
the password is at risk while being sent by the user.
How do the professionals do it?
**EDIT:
Im planning on storing the password as a hash, with a unique salt.
If anyone gets a hold of the password (if SSL is compromised) does that mean that a hacker can gain access without a problem?
In a regular username/password login, the password is always sent to the server. Ideally, the server then hashes the password input and compares to the hash stored in the database - using a unique salt for every password. Like #Sneftel said, when you use SSL the passwords aren't being sent in plaintext.
Think about it; if only the password hash was sent to the server, and the server compares that to the hash in the database - how would that be any different from just storing the passwords in plaintext in the database? It would be enough for any attacker to get the hash in order to get entry into the system.
The security issue here would be that the password themselves are stored in plaintext in your database - that's not a good idea. There are a few tips here: http://alias.io/2010/01/store-passwords-safely-with-php-and-mysql/
You may use some javascript program at client side to encrypt the password. But that requires the user to execute that script, which can be a problem:
Some users cannot execute that script, because they access your page with a program that does not support javascript. An example could be a program that is intended to load the page and get some specific value out of it.
Some users don't want to execute that script.
So, hiding the password while being sent to the server is not that easy.
Anyway, you mentioned that you send the data using an SSL-encrypted connection. That is the usual (and usually secure) approach for that situation. The disadvantage is that, if your SSL implementation has a flaw (eg. the Heartbleed bug), your passwords are usually broken, unless you do not use the server key for encrypting the connection data (this is called Perfect Forward Secrecy).
Regarding your database, you should never store plain-text passwords in it, unless you are required to do so without the possibility of changing that requirement. You always should store the salted password hashes.

Using Laravel auth::attempt with hashed password

This seems like a really easy one but I really can't figure it out. I want to use Auth::attempt($credentials) in Laravel 4 but with a password that has already been hashed (since it's an API). It works when I send the unhashed password, but I don't understand how to tell Auth to “not hash” the given password.
Quick “demo”
What works:
Auth::attempt([Request::getUser(), Request::getPassword()]);
curl --user username:notHashedPassword localhost:8000/api/
What doesn't work:
Auth::attempt([Request::getUser(), Request::getPassword()]);
curl --user username:$2y$08$xo7HpxFyeF2UKHOYs/e localhost:8000/api/
Are there any arguments I could pass to Auth::attempt() that would tell it to use it as it is instead of trying to rehash it (as I think it does)?
You can login the user manually
$user = User::find($id);
if ($user->password == Request::getPassword()) {
Auth::login($user->id);
}
You really shouldn't be hashing the password before you are sending them. How are you going to be able to hash the password properly prior to sending it without the salt? If you have access to the salt before sending the password then why are you using an API?
If you are worried about security of passing an un-hashed password, then you should be using SSL to ensure a secure transfer of data.
Don't consider an API any different then using a web page -- and you don't salt passwords before you submit a form on a website, instead if you need that level of security you rely on https / SSL.
The hashing method used by Laravel generates a different hash each time (even for the same string). You can read more about this in Hashing for Laravel. As you can read, it doesn't hash both strings and compare them, instead it uses the unhashed string to compare with the hash.
If you really do want to do this you'll need to implement your own Auth Provider and a different hashing algorithm that allows you to compare hashes.
If you're concerned about security you should consider HTTPS so that secure details (including passwords) are never sent in plain text.

How do I authenticate and validate a password?

I don't really know even what questions to ask here. My problem statement is simple: I need to store a password on the DB with a salt, validate an entered password against the stored password, and authenticate the password using a random challenge word whenever a user tries to log on. I am using php/javascript.
In trying to figure this out, the problem I am having is that if I pass up a challenge word in an html form, then hash the entered password with that word, I can authenticate the password on the server, but I can not separate the password from the challenge word so I can validate it against the salted password on the DB. If I send the password to the server in the clear or hash it without a challenge word, I can validate it but now I can not reliably authenticate it.
I think I need a 2 way algorithm of some sort so I can encrypt it with a key, and then authenticate the key while validating the password. How do I do it? or if it can't be done then what should I be doing?
Encrypting a password with client-side scripting is generally a bad idea. The proper way to do this is to use SSL.
Also, never store password in cleartext. If you must use a method like the one you describe above, hash the password twice: once for storing it in the database, another time for the two-way authentication.
To store a password, generate a random salt. Store HASH(password+salt) and salt. (Either the server or the client can do this computation.)
To perform an authentication, the server looks up the salt and HASH(password+salt). It then generates a random challenge and sends the salt and the challenge to the client.
On the client, prompt the user for the password. Compute: HASH( HASH(password+salt) + challenge). Send it to the server.
On the server, you already have HASH(password+salt) and you have challenge. So you can also compute: HASH( HASH(password+salt) + challenge). Compare this to what the client sent you. If they match, the password is correct.
Note that this is vulnerable to a MITM attack, so it should be used over a connection that is itself protected from a MITM, such as an SSL connection.

Categories