11

For fun, and in my spare time I'm creating a simple CMS for my own purposes (with hopes to release for wider use... later), using PHP. I'm currently working on the login scheme now, and have a few questions.

Note: The end result is always passed through crypt using blowfish and a cost parameter of 15 (Generally hoping that a cost param of 15 is long enough to hurt hacking attempts, but not long enough to frustrate users.)

Question 1: Assuming I'm using SSL/TLS: Do I really need to obfuscate the password any, before passing it to bcrypt (with the given parameters and a proper salt) and pushing it to the database?

Question 1.a: Since I don't have access to SSL/TLS (too costly from my webhost at the moment), is using the whirlpool hash (or something from the sha-2 family) client-side on the password before passing it to the server, a "good enough" case of security, or is that hash vulnerable to rainbow table attacks? (This assumes that I'm trying to put a tent flap on a tent, not on a bank vault. Bank vaults can afford SSL/TLS.)

Question 2: Is it worth it to create a new salt for the password every time the user logs in again, or do I just need to create a unique salt for that user of appropriate entropy when they register, and leave it?

D.W.
  • 98,420
  • 30
  • 267
  • 572
Mike S
  • 404
  • 2
  • 11

4 Answers4

12

Q1: "obfuscating" the password buys you nothing here, in terms of security; it just makes the code more complex, which is a bad idea.

Q1a: The hash of the password is "password-equivalent": presenting it is enough to get authenticated. So hashing changes nothing to security: this is equivalent to exchanging the password in cleartext. For security, you really want to use SSL -- you will not get much security without it. Actually you can forget all about crypt() and Blowfish and the "15" iteration count until you have enabled SSL: the lack of SSL is a much wider security issue. crypt() with Blowfish is very good, but using it without a SSL-protected password transfer is like putting a steel padlock on a tent flap.

Q2: The point of the salt is to be unique per password instance; a big enough random salt ensures such uniqueness "probabilistically". So you change the salt whenever you create and change a password (i.e. when you add a new user account, or when a user changes his password). There is no need to re-salt a password which does not change.

Thomas Pornin
  • 320,799
  • 57
  • 780
  • 949
  • wrt Q1a, even though the hash is password equivalent, it is not the password - hashing is designed to prevent damage due to leaks. However, an attacker who can intercept and read network traffic can probably also alter traffic - eg, by introducing custom javascript to capture the password before your javascript hashes it. That the password is not any better protected is an important argument against javascript hashing. – Iiridayn Oct 08 '12 at 16:53
3

Q1: Assuming you're doing it the 'conventional' way:

  • an end user fills out a HTML form,
  • which is served over HTTPS,
  • the response going over HTTPS back to your webapp server,
  • which is connected to your database server over a trusted network (i.e. both webapp server and database server are secure systems on a secure LAN)

then nope, don't obfuscate the password before it arrives at your webapp (PHP) code in the form submit.

But -- you're planning on using PHP crypt(), which offers you several ways to get yourself into trouble, f.x. by using MD5. Why not use a higher-level library optimized for secure password storage? I'm no PHP programmer, but PHPass seems a common choice, used by fx Wordpress. Otherwise look on Stack Overflow for "PHP bcrypt" or "PHP scrypt".

Q1a: There is no security here if you're not using HTTPS. Your "tent flap" analogy is apt, you're not even going to stop children with flintstones... Basically, don't do this. And if you do so, drop all thoughts about hashing on the client side "for security". Change to a webhost who offers HTTPS.

Q2: You only create a new salt if/when the end user changes his password. Never change it otherwise, the salt is needed whenever you verify a user password (i.e. every time a user logs in), so with a wrong salt, the users cannot log in.

  • The idea with creating a new salt would be that you verify the input with the old salt, then create a new salt, re-hash the input, and then store that and the new salt in the db. Does that add nothing to security, or does that have some weight to it? Thanks for the answers! – Mike S Apr 25 '11 at 19:37
  • 1
    @Mike S: About re-hashing the password and storing it again on each login: Honestly, I don't know. Gut feeling, since you're using the same hash algorithm each time, it doesn't add anything significant to security, but it complicates code and as such might introduce bugs. Personally I would not consider this; but perhaps someone else here has a more precise answer on the security implications. –  Apr 25 '11 at 20:07
0

Q1: In theory you don't need to obfuscate the password further, aside from addition of a salt before hashing. This will just increase complexity, not security value.

Q1.a: Hashing the password before sending it across the wire will only prevent an eavesdropper from reading the password itself. It won't protect from replaying the hash, and logging in as that user. The connection really should be over SSL.

Steve
  • 15,155
  • 3
  • 37
  • 66
  • Good points on both, thanks for the answer. Any stab at Question 2 yet or no? – Mike S Apr 25 '11 at 19:19
  • Simply hashing the password before sending it wouldn't stop anyone who tapped the SSL link (such as an SSL proxy which a machine is configured to go through) from replaying that password for that system, but if the hashing is done in a system-specific fashion it could mean that someone with access to the SSL proxy logs would be limited to just replaying it on *that* site, as opposed to getting a password which could be tried on other sites. – supercat Feb 02 '14 at 22:52
0

1) nope. Obfiscation is more so that the admins can't tell what the password is

1a) LET ME BE CLEAR: you should always, alway, always use SSL.

A better question is; that has the same answer is; lets say that you have an SSL connection on a third party provider due to the arrangements of your contract with them, but you don't want to run the risk of them sniffing your users information(passwords, anything really). and out side of there scouts honor, you don't trust them. Along with that, you could use a canary on the input field to make sure its the user you sent the data too.

Answer: You can for do public-key cryptography on the JS side before sending the data over. This is NOT the same security as SSL, but provides another lay of security that can be used.

I have been in that situation, where the partner had the SSL certs, and could sniff our data, and we used a system like that.

Jdahern
  • 121
  • 2