Hacker News new | past | comments | ask | show | jobs | submit login

Passwords that can be decrypted reliably are isomorphic to passwords stored in plaintext. That is very undesirable. Even assuming they are encrypted with a strong key, anyone with access to the decryption key and the database can trivially recover any password stored by such a system.

Password hashes are not isomorphic to plaintext passwords, because there can be collisions. That means there is no function to reliably take the stored passwords and turn them back into plaintext passwords; therefore, while reversing some/most passwords through complex iterative functions (e.g. brute force) is possible, the amount of work (particularly for bcrypt, pbkdf2, or other many-round hash+salt schemes) on average is many, many orders of magnitude greater than applying a decryption key. For good passwords, the amount of work is not quite unbounded, but might as well be.

It's true that plaintext passwords and singly-hashed md5 passwords are both quite bad, but at least with the md5 hash nobody can (I think?) currently crack a 32 character random string since there are no rainbow tables for such long passwords. (Assuming the password is vetted for common weaknesses, since "random" alone does not guarantee anything. "aaaaaaaa" is a random 8 char password, after all.) Functions that attempt to reverse non-isomorphic mappings end up being complex and, even in the case of rainbow tables for (unsalted) md5, are much slower than not having to recover the unencrypted password at all, or having some master key that decrypts all passwords.




When we're talking about passwords stored "encrypted" on customer-exposed applications, I agree.

When we're talking about passwords "vaulted" in non-exposed systems used for customer support, I have a harder time getting upset about it. I don't like systems that work this way, but I see the support/security tradeoff and it's a valid one.

It is likely but not certain that the site in question here did not go through the trouble of setting up a non-exposed secure password vault system for customer support people to use under supervision. Probably they do just store passwords in a column somewhere. But you don't know for sure whether they do.

Nobody needs rainbow tables to crack passwords.

http://codahale.com/how-to-safely-store-a-password/


> When we're talking about passwords "vaulted" in non-exposed systems used for customer support, I have a harder time getting upset about it. I don't like systems that work this way, but I see the support/security tradeoff and it's a valid one.

Worth also knowing is that many ISP's store your password using reversible encryption, because if a customer calls up wanting to know their password, it doesn't have to be regenerated. Which can save a lot of time re-configuring modem PPP credentials with your average Joe.


ISPs providing any kind of authenticated PPP store your password in cleartext, because PPP authentication does not work without storing cleartext passwords.


PAP doesn't require the server to store cleartext passwords.


If a customer calls up wanting to know their password, I would bet that they are configuring a new modem and that's why the need it. If their modem knows the password, why do they need to know it?


Email, ftp access, ssh access. There are lots of other reasons for needing to know a password.


I think elithrar was talking about the layer-2 modem password, not the layer-7 application user credentials.


What makes you think they are different?


If you're implying that Newegg or any public-facing authentication system could be implemented with a non-exposed password vault, then I don't see how.

If user passwords are encrypted with symmetric encryption, either the application must have access to the key in order to compare your provided password to the password stored in the DB, or the DB has to have a stored procedure with access to the key.

Therefore it's not -only- customer support that has access, but anyone who hacks the production system also gains access to the key. Of course there are ways to obscure that if it's kept in memory and required as input before the server starts up, but theoretically it's available to anyone who compromises the relevant server.

(And even if there were a system that were implemented as you describe, with access allowed only when a support staffer and a supervisor provides an asymmetric key each, who supervises the supervisors?)

(edit: The offered suggestions show that I wasn't considering non-symmetric or non-software approaches; in any case, at best those seem like complicated band-aids for a situation that should not exist.)


It could either:

  A) Have a traditional hashing scheme independent of the vault
  B) Use public-key encryption, and give the production 
     system only the public key.  The server could encrypt 
     the provided password for decryption by the private key, 
     and then compare ciphertext.  The vault simply has the
     private key.
Neither of these systems are ideal, especially the latter, but they do get around the one particular issue of a hacked frontend.


Why is (B) not ideal? Sounds like you get the usability (recoverable passwords) without the security issues (assuming that you properly separated the keys, etc.)

I ask because I am writing an app currently that stores an SSN. The data are downloaded for later use on non-public facing machines, and the SSN needs to be decrypted at that point. I am saving the data using PKI, and will be able to decrypt it later (but anyone without my keys won't be able to).


The main reason I was thinking of is that it's very difficult to do public-key encryption correctly. The normal advice is to just use GPG (or a similarly battle-tested library). The way these work makes ciphertext comparison meaningless. That's a good thing for almost all applications, but not for this one. The alternative is to use code that has not been so thoroughly battle-tested.

Your application is a much more straightforward application of PKI. You don't need to compare ciphertext, so you could just use GPG. (Please consult someone more expert than me, though. I am not responsible if there's a security problem, etc, etc).

As a secondary reason, public-key encryption is "fast by design", while password hashing techniques are hopefully not. This makes brute-force attacks easier. This actually applies more strongly to SSN's (only a billion possible combinations? Simple!). This can be worked around by adding a properly secured password hash of sufficient length to the plaintext, essentially adding the additional computation of the password hash.


Read this survey paper, particularly the very basic RSA attacks:

http://crypto.stanford.edu/~dabo/pubs/papers/RSA-survey.pdf

and ask yourself how comfortable you feel about directly using RSA in any context other than encrypting a randomly generated (semantically void) binary encrypting key under secure padding.


Very interesting skim; I'll have to make a few passes and digest it fully when I get the chance.

Is there a particular attack you're looking at here? I assume it's one based on Coppersmith's theorem, as that section was complicated enough that I'll need a few passes to digest it.

Of course, the plaintext could be voided of any semantics by using still more encryption. The simplest way would be to apply a "public" one-time pad to the plaintext. (edit: Different for each plaintext, of course; otherwise, it's not one-time)

The answer to the question I'm asking myself, of course, is "Not at all." I would use a dual-stacked hash/vault system built on high-level libraries if I were implementing something with these requirements. This involves the least new code, limiting both the time and number of mistakes involved.

I treat that as a different question than the purely-theoretical question of whether such a system could be secure.


Among the many reasons not to try implementing this is the fact that secure public key encryption is randomized.


I'm not sure I follow your statement. How would you recommend that I encrypt a piece of data to store into a database? It needs to be reversible (encryption, not a hash), but does not need to be reversible on the production system (the field just needs to be decrypted before analysis, on different machines at a later time).


You could use public key encryption in a cryptosystem to store rows in a database. The "correct" way to do that would be to use /dev/random to generate a 128 bit AES key, encrypt the data with AES, and encrypt the AES key with RSA. That gets you "reversible on one server but not another".

But you're looking for something beyond that; you want "semi-reversible and deterministic". Determinism is not typically regarded as a feature in cryptosystems. Secure RSA schemes go out of their way to avoid it (read Wikipedia's OAEP article as a starting point).

Generally I think it's a very bad idea to get involved in custom cryptosystems just to store passwords.


I'm a little lost, perhaps I'm not explaining my problem too well. I really appreciate your assistance so far, and I'll try not to waste too much more of your time or space in the HN databases.

If you have a quick link about your first paragraph, that would be appreciated. I'm not sure exactly what that means -- I understand what you mean bygenerate an AES key via /dev/random (gives us nondeterministic key), then encrypt the data with AES. However, why would I use a symmetric encryption system rather than a private/public key pair? With a priv/pub pair, can't I encrypt the data on the server but not be able to decrypt it?

Again, thanks for your help. I'm not actually storing passwords -- those I properly hash. The problem is that my data app has a requirement to collect SSNs (and they need to be reversible, although that can be offline at a later date). Oddly enough, the data requirements only state encryption is required for that -- most of my colleagues are using symmetric encryption with the passphrase stored on the server itself! I was just hoping I could build a system that would be able to encrypt the data, but not decrypt it (the decryption would be handled by another machine not available to the public).


Use GPG to encrypt the SSNs. You'll be fine.


I'm implying that customer-facing systems use secure hashes, and that the company also stores encrypted passwords on a server not exposed to the Internet.


The work could be done on a hardware security module, so the key never leaves the well-guarded environment. That would also make a good gatekeeper for requests for the unencrypted password.


> Passwords that can be decrypted reliably are isomorphic to passwords stored in plaintext.

This is absolutely correct, and I feel some readers may not exactly understand it. It would be one thing if only you had the key to decrypt the password (as is the case for example when you sync your browser data in Google Chrome). When the same people have access to both your encrypted password and the key to decrypt it, your password is only as secure as your confidence in the company's policies and employees' integrity.

Also, as a side note I should mention that even if Newegg was securely storing your encrypted password and key, they forfeit that when they email it to you in plaintext.


> your password is only as secure as your confidence in the company's policies and employees' integrity.

Thats always the case. Encrypted password or not. There's nothing stopping them from getting your password the next time you log in.


That's certainly true, although such an act would essentially constitute willful deceit at a company policy level, which is much worse than what I was hinting at. The hypothetical situation I was hinting at was something like an unruly employee being able to circumvent the company's process due to lax enforcement, even if the company's process itself was reasonable.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: