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.
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.)
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.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).
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.
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.
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.
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.
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).
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/