8 ms·
How are you going to calculate the scrypt hash, client-side? Doesn't that scrypt hash then become the password, from the server-side application's perspective?
by sarciszewski 11y ago
How are you going to calculate the scrypt hash, client-side?
Doesn't that scrypt hash then become the password, from the server-side application's perspective?
How are you storing the salt for the user if your server only knows about a SHA-256 hash.
> MITM attacks won't get access to unencrypted fields.
That's TLS's job. If you, for example, are building a web app and you're delivering Javascript to perform the scrypt calculation, a MitM can replace the code to exfiltrate the user's plaintext password. It doesn't make sense for the threat model.
- sinatra 11y agoVery valid questions. Let me try to answer them and let's see if those answers are valid or not. Yes, the scrypt hash just becomes the password for the server. However, this password is going to be unique and almost impossible to guess. Salting this password on server side doesn't give us any additional benefits. The server can store the salt that the client used, though. Yes, the MITM point was minor. Just another minor security benefit on top of TLS (which takes the majority of the burden of securing against it). So, maybe I shouldn't even mention this point.
- owenmarshall 11y ago>Yes, the scrypt hash just becomes the password for the server. However, this password is going to be unique and almost impossible to guess. Salting this password on server side doesn't give us any additional benefits. I don't even your threat model. Can you walk us through how you see this working? Client takes 'crappypassword' as input, sends p = scrypt('crappypassword') The server stores SHA256(p)? EDIT: misread what you said. is this correct?
- sinatra 11y agoYes, now it's correct.
- AstralStorm 11y agoAnd still invalid. Are you assuming that collisions against SHA256(bcrypt(p)) are harder than SHA256(p), right? Any math to prove that? Otherwise, you're relying on the user side to properly safeguard bcrypted password. That is often wrong. You cannot store any kind of transformed password anywhere, or it's no longer a password, but a token. Yes, those "Remember me" things transform passwords into tokens. Tokens can be stolen.
- timv 11y agoNote: I'm not endorsing the client-side scrypt/bcrypt approach, but I do think it's interesting. I'm going to refer to bcrypt because that's what your comment used, but the parent post used scrypt. > Are you assuming that collisions against SHA256(bcrypt(p)) are harder than SHA256(p), right? I don't think it is. I think it's assuming 2 things: 1. That SHA256 collisions are rare enough, and SHA256 attacks are hard enough, that they can be ignored. 2. That the output space of bcrypt is large enough to overcome the risk that salting is usually designed to overcome. On the first point: This approach simply isn't worried about SHA256 collisions between passwords. Yes, it's theoretically possible that 2 users with different passwords and/or different salts might end up with the same hash. If that happened often then it would be an issue - if you had n distinct users in your system but only n/2 distinct hash values, then if an attacker had a copy of your password store, it would effectively double the pay-out each time they successfully cracked a user's password (that is, each cracked password would allow them to authenticate as 2 users). But in practical terms, collisions are going to be tiny, and you're really worrying about the case where n distinct users have n-1 or n-2 distinct hashes. That's not going to meaningfully change your exposure. What is more of a risk (and this might be the point you were making) is that if any of your hashes happen to collide with the hash of a known input, then you're screwed, and while that's unlikely, "unlikely" isn't an ideal protection. When you're storing { SALT , HASH( SALT || INPUT) } you're reasonably protected against such collisions because they would only be effective if the known input happened to start with the salt. What the bcrypt approach can offer is that it knows that the input to SHA256 needs to be the output of bcrypt, so you can refuse to accept anything that isn't 186 bits long (or 31 base64 characters, depending on your approach). That constraint might well be stronger protection than a salt, although I haven't run any numbers. Probably adding a salt is safer, and I was going to attempt serious analysis on this scheme I'd certainly want to test whether that was true or not. On the second point, salting is usually designed to work around the scenario where 2 users have the same password and therefore (absent a salt) would have the same hash. It is not specifically intended for the scenario (described above) where two users have different passwords that happen to hash to the same thing. In the approach discussed here, the input to the hash is the output from bcrypt. That value has already had a salt applied, so 2 users with the same original passwords would be providing different inputs to our hash function, so we would be storing different outputs. > you're relying on the user side to properly safeguard bcrypted password I think that's a genuine issue. You need to do a not-insignificant level of client-side processing on the user's password. You're relying on the browser disposing of that data securely. It's "just bits in RAM", but bits in RAM leak, and there's no way for the browser to know that the bits you were working with were sensitive.
- ddlatham 11y agoI think the simplest thing is for the server to generate a salt for every user and add a step for the client to request the salt for a given user. If you want to protect against account enumeration then you need to be able to generate consistent salts for accounts that don't exist also.
- Strilanc 11y agoI think the idea is that the scrypt hash does become the password, but it's a better password. A password with a lot more entropy (kinda). The increased kinda-sorta entropy makes the use of a slow key derivation function on the server side unnecessary, so SHA-256 becomes sufficient. Not sure how I feel about it.
- sarciszewski 11y agoI feel that this is needlessly dangerous, personally. How are the salts managed? This detail is important. SHA256(scrypt(password, constant_value_instead_of_salt)) is going to produce collisions in the stored hash.
- owenmarshall 11y agoI think he's going for SHA256(scrypt(password, salt, work_factor)) and saying the bare SHA256 is sufficient. As opposed to SHA256(salt+scrypt(password, salt, work_factor)). I think it's dangerous because of the dependence on the client, and useless because scrypt(password,salt,work_factor) on the server is plenty hard to attack.
- sinatra 11y ago> useless because scrypt(password,salt,work_factor) on the server is plenty hard to attack. It enables DoS attacks, though, right?
- timv 11y ago> scrypt(password,salt,work_factor) on the server is plenty hard to attack For a large enough work_factor. In practice "large enough" is usually interpreted to mean "something that seems safe without being so large that I need to buy lots more servers" The argument (which I'm interested in, but not yet sold on) is that moving the scrypt to the client allows you to pump up the work_factor even higher than you would have been willing to do on the server.
- 11y ago
- technion 11y agoI don't hate the idea of putting this piece: base64_encode(hash('sha384', $password, true)) In client side JavaScript. I've seen my own passwords scroll in front of my eyes when debugging servers and reading POST variables. It's a minor level of shoulder surf protection before it hits the proper hash on the server.
- sarciszewski 11y ago"shoulder surf protection"?
- majewsky 11y ago"Shoulder surfing" refers to people extracting personal information, such as credentials, from your computer by just looking over your shoulder while you're typing them in or displaying them. Precisely the reason why password input fields usually display replacement characters instead of actual characters (or nothing at all if you're on a Unix terminal).
- sarciszewski 11y agoHow would transforming it before sending it over the wire help here?
- majewsky 11y agoNot at all. If I want to impersonate someone, I just have to act like them. The only protection is 2FA.