2

A naive developers might store a password in the database directly, which would then be compared directly with the password sent from a client. A more security conscious developer might instead store only the hash of the password in the database, and then compare the hash of the password from the client. But most people use the same few passwords for their accounts. As such, a site that requires an email and password for an account/login may then be given access to every other site for which the user supplied the same email + password.

So what if the client were to create the hash itself? In this case, the hash would be sent to the server, but again it doesn't matter - if I know what hash you use to log in to google.com, the hash will be the same for amazon.com (assuming the same algorithm). So how about appending a string from the server onto the password, then hashing? Example:

  1. I go to amazon.com, and am asked for my credentials
  2. With the login page, amazon sends a guid: 'cdfefe81-d466-49a6-acea-140fa52c0901' (this may be associated with the user account, or just have 1 for all of amazon)
  3. I enter my password, 'safe_password'
  4. The client append the guid to create 'safe_passwordcdfefe81-d466-49a6-acea-140fa52c0901'
  5. This is hashed using whatever hashing algorithm is appropriate, and then sent to the server. Inside the server, the hash is re-hashed (with a salt) and compared with the hash in the database to authenticate.

The advantage of this flow allows a user to use the same or similar passwords for multiple servers, and as long as all such clients follow this pattern, no server would ever know the users actual password, even if that server were compromised.

Edit:

To clarify, the goal is to protect the user's password, assuming a server is completely compromised. If I run a site that requires login, by receiving a salted hash from the client (where I provide the salt), even if a malicious user has access to all the data on the server side, they would never be able to find the user's original password, assuming a good hashing algo, which would significantly limit the potential impact to users for a security breach.

Another application would be credit card numbers, which are a lot like passwords. Imagine this scenario: I am responsible for validating credit card numbers at Visa to approve charges. Amazon wants to use my service, as does every other major vendor in the world. So I tell Amazon "I won't authenticate any credit cards from directly from a number. Instead, I'm going to require you send me a hashed version of a string, and since you've registered with us as a vendor, here is a GUID that will be assigned to your account". The string would be something along the lines of <cc#>:<expiration>:<GUID supplied *to Amazon* by Visa>.

So this whole flow:

  1. Amazon wants to process CC's, requests GUID from Visa
  2. Visa generates GUID, sends to Amazon, and associates the GUID with the account
  3. Amazon sends GUID with credit card input page to buyer
  4. On client side, after CC info is entered, this information is never sent to Amazon unhashed Instead, the client constructs the string as described above, hashes it, and sends the resulting hash to Amazon.
  5. Amazon wants to allow for repeat orders, so it stores this hash in their database.
  6. To authenticate, Amazon uses existing S2S authentication model to prove that they are Amazon.com, and sends the hash from the client, along with the buyer's name, address, etc.
  7. Visa receives said hash, looks up Amazon's GUID, and finds all cards owned by the specified buyer. For each card of the buyer, Visa re-constructs and re-hashes the card number + exp date + Amazon GUID, and compares the hash with what was received from Amazon.
  8. Visa finds a match, says Amazon is OK to charge this card, and Amazon sends a confirmation of said charge.

Given this flow, even if I were to gain access to all of Amazon.com databases, servers, hard drives, emails, incoming traffic, etc, I would never know the user's credit card number. The most harm I could possibly inflict would be if I can spoof being an Amazon.com server, I may be able to charge the user on behalf of Amazon.com, but that would presumably then go into Amazon.com's account, so I wouldn't likely benefit from this at all. In an ideal situation, this flow would be part of the SSL logic, such that only site that implement something of this nature receive the lock symbol in client browsers (haven't thought this through entirely, but seems plausible)

Rollie
  • 121
  • 2
  • So where would you store the GUID (since you'd need it to log back in later)? – tangrs May 24 '15 at 11:02
  • 1
    I only find a proposal for an authentication scheme. What's your question? – Jens Erat May 24 '15 at 11:03
  • The guid would be stored on the server, sent to client(s) via SSL. The question is in the title. – Rollie May 24 '15 at 11:45
  • @Rollie that's unrealistic, because you don't know what guid to serve to whom. See my answer, let me know if you want me to elaborate on that. – Steve Dodier-Lazaro May 24 '15 at 12:42
  • @SteveDL the GUID served could be based on the client. Or, all clients could receive the same guid. Lets go with the simpler (latter) case: all clients of amazon.com get the suggested GUID, thereby differentiating the password when logging into amazon vs other sites, even if you use the same password. – Rollie May 24 '15 at 13:00
  • 1
    If you give the same guid to all clients of a site, then I as an attacker can trivially retrieve it and serve it with a spoofed password from a third-party site. That's not security you're doing then, it's just added complexity :-) – Steve Dodier-Lazaro May 24 '15 at 13:02
  • yes, if the 3rd party site also didn't implement the same security. Assuming the attacker doesn't have access to the client side, an admin on amazon.com would never know what the user's google.com password was, even if they were the same password. – Rollie May 24 '15 at 13:41
  • Alright, could you please post a very precise threat model? Which attacks do you prefer to avoid, and which do you not? – Steve Dodier-Lazaro May 24 '15 at 13:51
  • Note that quite a few candidates for the [password hashing competition](https://password-hashing.net/) perform some kind of balancing between client & server. – Maarten Bodewes May 24 '15 at 17:03
  • Take a look at "Salt" and "pepper" for passwords... seems like a dupe – makerofthings7 May 26 '15 at 16:09

2 Answers2

2

Your scheme would not work as it is, because the Amazon server has not authenticated you when you arrive on the login page yet. So it must let your client browser decide how to create a unique guid. If the server tried to calculate a unique guid based on known attributes such as your IP address or browser fingerprint, you would be unable to connect from multiple devices or locations.

All browsers on all devices would then need to process guids in a similar fashion so users can get a consistent guid. That means users would authenticate to their own device, in some way or another. Let's assume that the guid is a combination of a user credential passed on to the browser, and the domain name of each website to prevent spoofing. You now can create unique passwords, with two strong constraints:

  1. you don't handle sites that have multiple domain names
  2. you need compatible equipment

The first problem could be solved by having browsers and sites communicate lists of trusted domains just like for the Same-Origin Policy, and public APIs for browsers to query the trusted domains of a 'parent' domain used as a seed for the guid algorithm. This is mostly infrastructure, nothing impossible.

The second problem is more serious. Your original goal is to make password spoofing worthless, or in other words to make all clients generate unique credentials per user/domain (in which case, by the way, the whole idea of a password is superseded). If that were to be adopted, you'd need all websites and all clients to be immediately compatible. If not, then users would encounter situations where they need to provide a unique guid-based password to a site but cannot calculate it, or where they can calculate a guid-based password but have to use an old, stealable password.

Note how you've imported one of the major problems of password managers that create unique passwords: you have to keep access to the manager to avoid being locked out! If you wanted to keep a compatibility layer that allows you to connect with your old stealable password, then that password could be spoofed and reused.

There is still an application to your idea, however: the unique of a guid on top of an original password could give websites a slightly higher degree of confidence that you are a legitimate client and not a spoof. This sounds great but it's not necessarily enough for large service providers, which are often confronted to compromised devices, and not just with stolen passwords. A compromised device would provide an attacker with a means to generate all your guids for all your websites (since your secret can be extracted). In the end, you have both the same inconvenients and attack surface as a password manager, because that's pretty much what you've created!

Steve Dodier-Lazaro
  • 6,798
  • 29
  • 45
  • The key difference is the *server* sends the guid - it's not generated by the client. Please amend answer with this in mind :) Consider the protocol to be an addendum to TLS, in that 'if the header X-ClientSalt is present, append it to the password, and send the hashed result'. some clients might support, some might not. – Rollie May 24 '15 at 12:56
  • 1
    You can't do that. How do you authenticate the client so as to send them the correct guid, for the purpose of... authenticating the client? – Steve Dodier-Lazaro May 24 '15 at 13:00
  • You can, however, provide a scheme similar to what you propose to identify previously known devices on previously know IP addresses. – Steve Dodier-Lazaro May 24 '15 at 13:01
0

I still think, the problem is not yet addressed. Which is the asset you are trying to protect? the password or the password hash? Is it the stored password / password hash or while transit?

Some disconnects / or clarity requirements

I go to amazon.com, and am asked for my credentials. With the login page, amazon sends a guid: cdfefe81-d466-49a6-acea-140fa52c0901' (this may be associated with the user account, or just have 1 for all of amazon)

Not sure how to identify the client. Possibly, if you have the server to ask username and password one at a time, this could work, but if the username and password fields are serviced from the same page, it might no. Keeping it same for all the users might defeat the purpose.

They key is, this should be a repeatable process on all devices, known/unknown clients etc. and is not

I enter my password, 'safe_password'. The client append the guid to create 'safe_passwordcdfefe81-d466-49a6-acea-140fa52c0901'. This is hashed using whatever hashing algorithm is appropriate, and then sent to the server. Inside the server, the hash is re-hashed (with a salt) and compared with the hash in the database to authenticate.

So if the password 'safe_password' is in the hands of an attacker through a compromised website would this process stop him from the amazon.com account?

This solution might have a place, such as client machine authenticated environments.

knight007
  • 1
  • 2
  • Ignore the client identification for the initial request; it could be done as part of a multipart communication, but easier to consider when Amazon.com has one public GUID salt they provide to all clients. Updated question with what I hope is a clearer example. Re your last point: once the user's password is *actually* compromised, all security is still lost. This scheme is designed to provide security in case of a server breach. – Rollie May 24 '15 at 20:25