In usual scenarios, the connection string contains the password in plain text, but this can be captured by Wireshark, so I want to use the encrypted password in a connection string. I found the below excerpt from the Postgres documentation:
Encrypting Passwords Across A Network The MD5 authentication method
double-encrypts the password on the client before sending it to the
server. It first MD5-encrypts it based on the user name, and then
encrypts it based on a random salt sent by the server when the
database connection was made. It is this double-encrypted value that
is sent over the network to the server. Double-encryption not only
prevents the password from being discovered, but it also prevents another
connection from using the same encrypted password to connect to the
database server at a later time.
If I understood it correctly, to get the salt, I need to connect to the database, but doean't that mean that the password can be spoofed?
I tried to google around but did not found a satisfying solution. I want to understand how can I get the random salt from PostgreSQL server using java and then encrypt the plain password with it and use an encrypted password to establish a connection.
If you, user arvind, set the password to secret, the actual password is set to
'md5' || md5('secret' || 'arvind')
that is md50624d6c2e831004efb7f4173699a1775. That's what you'll find in the pg_authid system catalog.
Now the establishment of a connection works like this:
client to server: I want to connect to database mydb as user arvind.
server to client: Ok, I want MD5 authentication. Your salt is g73j.
The client has been given secret as password.
First, it uses the formula above to get the real password (first hashing).
Then, the client hashes the password a second time using
'md5' || md5('0624d6c2e831004efb7f4173699a1775' || 'g73j')
client to server: the hashed password is md573ae1f550fb4bcd28411cefb24b800bc.
The server calculates the same hash and compares the result to what it got from the client.
If that is the same, the server knows that the client must have the real password, otherwise it couldn't have calculated the correct hash.
The password itself is not transferred, so it cannot be stolen by an eavesdropper.
server to client: Ok, you're in.
The actual messages look different of course, but that's all in the documentation.
Related
I am using angular for login & signup and encrypting the password with the crypto-js and the password is also getting encrypted from backend side(here the encrypted key of crypto-js is getting encrypted by backend(Java) and stored in database).
Now the question is how i match the password for login(because whenever i am logging in it's showing httpStatus= BAD_REQUEST, description= password not matched) ?
is there any frontend angular method to decrypt the string of backend ?
or any other solutions ?
I have tried multiple ways to encrypt the password same as available in the backend, but failed !
The encrypted password should be non-decryptable.
What usually happens is that the passwords get hashed. Of course you need to use the same algorithm as you did when setting the password to ensure that the hash values are the same.
See also How can I hash a password in Java?
I want to build a login application, that has a client for username and password input, as well as a server, which then recieves the username and the password.
The server should then check, wheather the password it recieved matches the already stored hash, or not.
I thought it would be smart not to send the password unencrypted (just in a String) from the client to the server, so I already encrypted it on the client side with BCrypt.
But now i have two hashes on the server-side, but BCrypt only offers the methode to compare a plaintext with a hash, not a hash with a hash.
Should I now send the password in plaintext to the server or is there a way to compare two hashes?
Thanks for your help
The simplest way would be to use TLS https://en.wikipedia.org/wiki/Transport_Layer_Security
"Challenge-Response" is the term you should google for.
The Principle:
On server side you have stored a hashed (salted) password and the salt.
The client sends first the login name.
The server looks up the salt of the login in the database and sends this to the client, together with a random string (That's the Challenge).
The Client has now to calculate an encrypted password in the following way: Concatenate login password with salt and hash it. Concatenate the result with the random string from the challenge and hash it. Send the result to the server.
The server now concatenates the hashed password (stored in user database) with the random string sent together with the Challenge and calculates the hash. The result must be exactly the same as the result recieved from the client.
You can fetch hashed value from database and compare it with sent value
I want to use an Android app to send an encrypted password to a PHP file on the server that stores it. This also works so far.
At login I send the encrypted password to the server again and the PHP file should find out if the password is correct.
But if I now
if (password_verify($userPassword, $hash)) {
}
then the function requires the real password and not an encrypted one. How can I now compare encrypted with encrypted ?
Or do I just have to send the visible password to an SSL server and it's still secure ?
Does it really matter what the $userPassword actually is? This could be encrypted original as long as that is what you stored the first time...
So just send the encrypted version, hash it (in PHP), store it (in PHP) and later verify that (password_verify($inAndroidHashedPass, $localllyStoredHashFromPHP)) ?
I'm developing an application that requires a user to login. On the server side I'm using PBKDF2 algorithm to hash passwords, but currently I'm sending password to the server as a plain text - String. And I do not know how change it. Now it is prone is sniffing.
What should I do to make this more secure?
I've dealt with the same problem, here's how I solve it
the client hash the password (SHA3-512) and sent it to the server, the server get this and hash it again using random and changing salt function, all connection is done via SSL and with POST methods
user enter 1234 -> client send hduhd73y743fhiuj4u -> server store on the database 37y487f.f4u4uj4o3i5885 (not actual values)
by this approach, the server will never know the actual password, so a man in the middle will can't get this actual password, keep in mind it doesn't stop a man in the middle to imitate this hashed password and sent it to the server to login as the user
In the login service, a user is posting a json as payload to a Spring RESTful login service like below:
{
"username": "john",
"password": "doe"
}
Once the Spring RESTful service receives the call, it compares the password with the one store in the database in plain text.
I see two problems in the current implementation.
The password is sent through HTTP as a POST payload in plain text.
The correct password stored in the database is in plain text.
For issue 2, I decided to use bcrypt to encrypt the password stored in the database as mentioned in this post. Is this a good way?
For issue 1, I don't know if there is a best practice for it. Can some one share your insigts? Thanks!
Edit:
Sorry that I forgot to mention that the client and server talks through HTTPS. And the password is sent in POST payload.
In this case, the solution to issue 2 (store bcrypted correct password) in the database is okay, right?
What about in issue 1, in this case, the password can be sent in the post payload in plain text?
Use HTTPS.
Password should be in request body, so use POST.
Don't hash the password before sending.
Compare hash stored in the db with hashed received password.
There is no reason to encrypt passwords. It's a bad idea. They should be hashed and preferably salted. In case someone stoles your database, it'll be harder to compromise your users' passwords.
How to securily store passwords.
As I understood, you want to hide/secure even when saving password. So that nobody can see password from request body.
Password should be hashed when saving in database. Even anyone steel your db he won't be able to compare passwords because he will get hashed password.
Usually, we send request body in logs from where we can take body in case of any error occurs for testing. You can stop request body to send in logs file only when you are saving password only.
In this way, only user will know the password. None of the developer can get password. But this can be a problem when user will get unknown error that you will have take care separately.
I am not shure to understand your requirement.
If you want the good practice, so xenteros is right :
Use HTTPS.
Password should be in request body, so use POST.
Don't hash the password before sending.
Compare hash stored in the db with hashed received password.
There is no reason to encrypt passwords. It's a bad idea. They should
be hashed and preferably salted. In case someone stoles your database, it'll be harder to compromise your users' passwords.
If you absolutly want to use HTTP and not HTTPS you can hash your password with javascript. Don't use encryption with javascript. Someone can reuse it to decrypt the password. And in general don't use encryption to store password for security reasons.
fastest MD5 Implementation in JavaScript
you should trully prefer the solution of xenteros