Skip to main content
It sounded pretty pompous before - the attitude isn't necessary
Source Link

I will mainly treat this as a learning exercise - youYou should never try to secure a "real" web application with a scheme that you invented on your own. I'll also disregard all theAs such we shouldn't discuss practicalities on how you would actually implement or use such a thingmethod.

I will mainly treat this as a learning exercise - you should never try to secure a "real" web application with a scheme that you invented on your own. I'll also disregard all the practicalities on how you would actually implement or use such a thing.

You should never try to secure a "real" web application with a scheme that you invented on your own. As such we shouldn't discuss practicalities on how you would actually implement or use such a method.

Reaction to edit
Source Link
averell
  • 1.1k
  • 7
  • 10

Don't use SHA-anything for hashing the passwords, use a dedicated password-hashing function such as bcrypt or PBKDF2 to make attacks more difficult (see this answer also). You can also use or add some TOTP mechanism for your app, which is better than just a password.

Addendum

You added the following after I wrote my answer:

My requirement is that the only thing users ever need to provide for successful authentication is their username/password and nothing else, regardless of what device they are using or whether they were logged in on that device before.

This explains why you want to send the private key back to the server, although it doesn't change the reason why it is a bad idea.

You could still use a challenge-response mechanism, like ThoriumBR suggested. There are even advanced challenge-repsonse mechanisms such as SRP which use clever math to avoid storing the password on the server.

However, all those mechanisms, and also client-side hashing (see this answer), have one thing in common:

They need to execute code on the client side.

In a web app, this can only be Javascript sent by the server. Implementing the client side is not the problem (there is even a OpenPGP library), but since you worry about the security of the https connection, you have another problem:

Any man in the middle could therefore simply inject malicious client side code to steal the password, rendering your whole clever mechanism obsolete.

Don't use SHA-anything for hashing the passwords, use a dedicated password-hashing function such as bcrypt to make attacks more difficult (see this answer also). You can also use or add some TOTP mechanism for your app, which is better than just a password.

Don't use SHA-anything for hashing the passwords, use a dedicated password-hashing function such as bcrypt or PBKDF2 to make attacks more difficult (see this answer also). You can also use or add some TOTP mechanism for your app, which is better than just a password.

Addendum

You added the following after I wrote my answer:

My requirement is that the only thing users ever need to provide for successful authentication is their username/password and nothing else, regardless of what device they are using or whether they were logged in on that device before.

This explains why you want to send the private key back to the server, although it doesn't change the reason why it is a bad idea.

You could still use a challenge-response mechanism, like ThoriumBR suggested. There are even advanced challenge-repsonse mechanisms such as SRP which use clever math to avoid storing the password on the server.

However, all those mechanisms, and also client-side hashing (see this answer), have one thing in common:

They need to execute code on the client side.

In a web app, this can only be Javascript sent by the server. Implementing the client side is not the problem (there is even a OpenPGP library), but since you worry about the security of the https connection, you have another problem:

Any man in the middle could therefore simply inject malicious client side code to steal the password, rendering your whole clever mechanism obsolete.

I will mainly treat this as a learning exercise - you should never try to secure a "real" web application with a scheme that you invented on your own. I'll also disregard all the practicalities on how you would actually implement or use such a thing.

Will it work?

Your scheme does not send a password over the wire. What immediately jumps out is that you send the private key to the server, which never does anything with it, for no reason. Yes, it is supposedly still protected by the password, but why?

As others have pointed out, the private key is supposed to remain with the owner.

Even if you consider the private key's password encryption, there is the following problems (at least):

  • Handing out the private key in your scheme is essentially the same as making the password hash public: Anyone can now do an offline dictionary attack against the key's password; and nobody can stop that.
  • Even worse, they can get the key for a given login, meaning that they can check if a user exists and then attack the password for the user name.

With a small modification, your scheme would be a very simple forform of public key authentication:

  • The client creates a key pair, and sends the public key to the server
  • To log in, the server sends out a random string.
  • The client signs the string and sends it back to the server.
  • The server verifies the signature to make sure the client has the private key

Something like this is actually already possible in https using client certificates. The same thing is used for ssh.

The Challenge-Response mechanism mentioned by ThoriumBR is another way of authenticating, although the implementation described there assumes that the server stores the password in cleartext -- which is much more dangerous than sending it over an encrypted connection.

Will it be "better"?

No. The scenario that you want to defend against is supposedly that someone gets inside the encrypted https connection. If you assume that this is the case, they would not only be able to read the password but also steal your session cookie and all the data that is shown in your session. In that case, the attacker has already won, regardless of wetherwhether they read the password or not.

You could of course roll your own encryption and authentication, but the question is why you'd think that this will be better than the https connection?

The realistic scenario isn't that someone breaks the https connection, it is that someone breaks into the server's database and tries to "recover" the passwords in an offline attack. This is what most authentication schemes try to defend against.

The danger with passwords is not that they are interceptinterceptable, but that they can be guessed.

What should you do in real life?

For a "real" web application, use an established framework and a well-known authentication library. Don't write it yourself, because it is easy to get wrong and very hard to get right.

Don't use SHA-anything for hashing the passwords, use a dedicated password-hashing function such as bcrypt to make attacks more difficult (see this answer also). You can also use or add some TOTP mechanism for your app, which is better than just a password.

I will mainly treat this as a learning exercise - you should never try to secure a "real" web application with a scheme that you invented on your own. I'll also disregard all the practicalities on how you would actually implement or use such a thing.

Will it work?

Your scheme does not send a password over the wire. What immediately jumps out is that you send the private key to the server, which never does anything with it, for no reason. Yes, it is supposedly still protected by the password, but why?

As others have pointed out, the private key is supposed to remain with the owner.

Even if you consider the private key's password encryption, there is the following problems (at least):

  • Handing out the private key in your scheme is essentially the same as making the password hash public: Anyone can now do an offline dictionary attack against the key's password; and nobody can stop that.
  • Even worse, they can get the key for a given login, meaning that they can check if a user exists and then attack the password for the user name.

With a small modification, your scheme would be a very simple for of public key authentication:

  • The client creates a key pair, and sends the public key to the server
  • To log in, the server sends out a random string.
  • The client signs the string and sends it back to the server.
  • The server verifies the signature to make sure the client has the private key

Something like this is actually already possible in https using client certificates. The same thing is used for ssh.

The Challenge-Response mechanism mentioned by ThoriumBR is another way of authenticating, although the implementation described there assumes that the server stores the password in cleartext -- which is much more dangerous than sending it over an encrypted connection.

Will it be "better"?

No. The scenario that you want to defend against is supposedly that someone gets inside the encrypted https connection. If you assume that this is the case, they would not only be able to read the password but also steal your session cookie and all the data that is shown in your session. In that case, the attacker has already won, regardless of wether they read the password or not.

You could of course roll your own encryption and authentication, but the question is why you'd think that this will be better than the https connection?

The realistic scenario isn't that someone breaks the https connection is that someone breaks into the server's database and tries to "recover" the passwords in an offline attack. This is what most authentication schemes try to defend against.

The danger with passwords is not that they are intercept, but that they can be guessed.

What should you do in real life?

For a "real" web application, use an established framework and a well-known authentication library. Don't write it yourself, because it is easy to get wrong and very hard to get right.

Don't use SHA-anything for hashing the passwords, use a dedicated password-hashing function such as bcrypt to make attacks more difficult (see this answer also). You can also use or add some TOTP mechanism for your app, which is better than just a password.

I will mainly treat this as a learning exercise - you should never try to secure a "real" web application with a scheme that you invented on your own. I'll also disregard all the practicalities on how you would actually implement or use such a thing.

Will it work?

Your scheme does not send a password over the wire. What immediately jumps out is that you send the private key to the server, which never does anything with it, for no reason. Yes, it is supposedly still protected by the password, but why?

As others have pointed out, the private key is supposed to remain with the owner.

Even if you consider the private key's password encryption, there is the following problems (at least):

  • Handing out the private key in your scheme is essentially the same as making the password hash public: Anyone can now do an offline dictionary attack against the key's password; and nobody can stop that.
  • Even worse, they can get the key for a given login, meaning that they can check if a user exists and then attack the password for the user name.

With a small modification, your scheme would be a very simple form of public key authentication:

  • The client creates a key pair, and sends the public key to the server
  • To log in, the server sends out a random string.
  • The client signs the string and sends it back to the server.
  • The server verifies the signature to make sure the client has the private key

Something like this is actually already possible in https using client certificates. The same thing is used for ssh.

The Challenge-Response mechanism mentioned by ThoriumBR is another way of authenticating, although the implementation described there assumes that the server stores the password in cleartext -- which is much more dangerous than sending it over an encrypted connection.

Will it be "better"?

No. The scenario that you want to defend against is supposedly that someone gets inside the encrypted https connection. If you assume that this is the case, they would not only be able to read the password but also steal your session cookie and all the data that is shown in your session. In that case, the attacker has already won, regardless of whether they read the password or not.

You could of course roll your own encryption and authentication, but the question is why you'd think that this will be better than the https connection?

The realistic scenario isn't that someone breaks the https connection, it is that someone breaks into the server's database and tries to "recover" the passwords in an offline attack. This is what most authentication schemes try to defend against.

The danger with passwords is not that they are interceptable, but that they can be guessed.

What should you do in real life?

For a "real" web application, use an established framework and a well-known authentication library. Don't write it yourself, because it is easy to get wrong and very hard to get right.

Don't use SHA-anything for hashing the passwords, use a dedicated password-hashing function such as bcrypt to make attacks more difficult (see this answer also). You can also use or add some TOTP mechanism for your app, which is better than just a password.

Additional link to another answer
Source Link
averell
  • 1.1k
  • 7
  • 10
Loading
Source Link
averell
  • 1.1k
  • 7
  • 10
Loading