Using Laravel auth::attempt with hashed password - php

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.

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!

CodeIgniter - Why does encrypting with the same key produce different results?

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!

Compare BCrypt hash to Bcrypt hash 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.

Should I encrypt passwords before sending via Basic Auth?

Very simple question. For registering and logging in through a RESTful API, should the passwords be encrypted before sending through Basic Authentication; or is Basic Authentication so secure that this would be unnecessary? This is sent through secure HTTPS.
Thanks for your insight!
imho, if everything is sent via https then everything is already encrypted anyway
In case you are using HTTPS it should be enough, but you can never be cautious enough so I would at least hash the password with MD5 + a Salt value.
You could use a hidden field to store the Salt value and then generate the hash trough something like <script>var fullhash=MD5(MD5(*value of the password*)+MD5(*value of the saltfield*));</script>
you can make any variations of MD5'ing the password and salt value and combining those, md5ing and so on.

Passing URL parameters with PHP

I am creating a program that communicates with a PHP script on a web server and to do so I need to be able to pass parameters from the program to the PHP script.
Now here is my question. At some point the user name and password needs to be passed to the script. Now this is not done in a way that is apparent to users (such as in an address bar) but I know with a little sniffing around someone that really wanted to could figure it out. So while my script is safe from injection, obviously variable tampering is an issue here.
This is an idea I have come up with so please help me wrap my head around it and see if this would work the way I THINK it will.
My thought was to encrypt the user password (or another unique key) variables on the client side before sending so you get a url like (obviously just made up) mypage.php?un=Oa348uty8&ps=op986hGTfreu Then when it gets to the PHP script decrypt it and encrypt it again with a different salt.
So when it leaves the application it would be encrypted but not the correct way, and then when it hits the PHP script server side decrypt it and re-encrypt it with the correct salt so it would correctly match the stored encrypted password.
This way, they user would not know what the encrypted version of their password is supposed to look like so without that they would not be able to tamper with the URL and try to insert fake values.
To put it in a nutshell, you are thinking of this:
On server side you have:
a database, with login/password matches.
a script that take 2 parameters (password and username) and check in the database if the couple exists
Your problem:
When your local application call the php script on server side, the 2 parameters are given in plain text. And you want to avoid tampering ( if your script are safe against injection i only see tampering used to bruteforce the auth <= keep in mind that i will keep this assumption in the whole post)
Your solution:
On client side, encrypt the 2 parameters
On server side, add a salt in your script to salt
Then decrypt the 2 parameters and encrypt with a salt
What I think:
This will not solve the tampering issue, someone can still forge requests.
The first encryption is useless because someone can retreive the key used by your client.
The second encryption is not safe enought because you use the same salt for all you users.
What I suggest:
Accept that tampering can't be avoided if you don't use a secure protocol like HTTPS (can either use SSL or TLS).
If you want an acceptable security without HTTPS the following is what i would implement:
A token system that you will check in order to see if the user can perform the login operation
A username that would not be encrypted
The password sha1 hashed stored in database
On client side, you call the script and provide the username as non encrypted and your password as a sha1 hash, rehashed with a random salt (sha1(sha1(pass)+salt) (the salt is stored in the user session on server side)
The script would then compared the provided hash with db password hash rehashed with session salt
The improvement is that the attacker must try to brute force two sha1 passwords consecutivaly and must provide a valid token to perform the login action. Plus if you use as salt a string using hex char of a variable even length, it will make the job harder for the attacker to recognised that the value bruteforced by the second hash is a sha1 hash, and even if he know it's an sha1 he will have to test multiple case to try to find the right portion of the value that correspond to the hash.
Because of variable salt, a same password won't be the same if hashed:
Imagine the attacker sniffed a hash and know which password was used then sniff another hash that was made with the same password as the other, the attacker won't be able to know that the 2 password where the same( a little overkill but still usefull).
It is safer to store the password as hashed value, because if the attacker manage to dump your user table, he won't be able to use the passwords right away, he would have to bruteforce each of then.
Finally sha1 hash are safer than md5 (i tell you that because you used the md5 tag in your post)
The downside of this method is that passwords can't be reversed, so you won't be able to given them back to your users if they lost it. You will have to make them set a new one.
An hardcore way (still without using HTTPS), would be to encrypt your password and username with a strong cypher (like AES or 3DES) and use a secure key echange algorythm (like the Diffie Hellman one) to exchange a random shared key.
This method won't block tampering, but will screw the attacker, because he won't be able to decrypt the value (assuming he only is sniffing the network). The key is random and never hardcoded in any of your application, so even if someone reverse your client, he won't be able to retreive a key.
I would still recommend to store your password value has hash.
An extreme way would be to merge the 2 methods but would be completly overkill.
Hope this will give you ideas
The problem with your approach isn't whether you are using encrpyted passwords and usernames in the URL or not. If the user authenticates by sending the encrpyted strings to you, then I as an attacker can still sniff out those hashes, pass them to your application and authenticate. This is unless then, that you do some public key/private key exchange before hand, but that is just reimplementing HTTPS, so you might as well just use HTTPS.
What you should do is to send the request using POST over HTTPS.
POST: So that the authentication details will not be in the URL and show up in logs and referrer URLs.
HTTPS so that the content of the whole request is fully encrypted and can only be decrypted by the client application and the server side.
encryption with Javascript from client to server only prevent from non SSL posting fails.
I think you must use sessions instead of this type encryption .
Update:
You could add your own secret key in both scripts.

Categories