Ask HN: How would you design password storage for a service like Mint.com?
I'm trying to figure out what best practices would be for a service like Mint.com.
Requirements: Allow users to store cleartext passwords to bank accounts which can be accessed by the service once per day regardless of if the user is logged in.
Usually, you only want to store hashes of passwords on your site but Mint can't do that, they need the cleartext passwords in order to log into banks. What is the safest way to store that customer data?
9 comments
[ 3.7 ms ] story [ 33.0 ms ] threadI'd store the clear text passwords encrypted with AES-256 CBC mode (still works right?). Next their would 3 databases, on 3 separate servers (hopefully physical ones). Server 1 passwords + salt, server 2 key 1, server 3 key 2. bcrypt(Diffe-hellman(key1,key2), salt) = AES standard key.
Basically I wouldn't. I couldn't sleep good at night storing financial data.
[0] http://www.moneysense.ca/spend/the-banks-take-a-bite-out-of-...
http://www.auricsystems.com/products/paymentvault-tokenizati...
Failing that, what you're probably looking for is something along the lines of a simulated HSM (let's call this an SHSM).
Decompose the system into four distinct services:
- The front-end application, "Mint" as experienced by normal users.
- A minimalized subset of "Mint", with Mint's chrome and UX, dedicated to the acceptance of credentials or secrets from users. Ideally, this is running on a separate instance.
- An SHSM system that exposes nothing but a simple remote API for sealing and unsealing secrets. Seal: secret->token; unseal: token->secret. The SHSM is on separate hardware, unshared by any other service.
- A backend system, hardened and carefully assessed (but not as hardened as the SHSM) that performs the operations that require the secrets and stores its results where the front-end can get access to them.
This design needs to recognize that:
* The minimalized secret-accepting front-end can be compromised and, if that happens, an attacker can "camp" n the front-end and collect secrets regardless of what else you do. That's why you segment this functionality from the main front-end.
* A serious flaw in the rest of the front-end might transitively give an attacker a pivot to owning up the secret-accepting front-end; this could be direct (for instance, if both share a database) or indirect (if the minimalized front-end renders attacker-controlled content accepted in the front-end).
* There needs to be a diode-like relationship between the secret-acceptor and the SHSM; the SHSM must allow the secret-acceptor to seal a secret in such a way that it can't later unseal it, else it's serving no real purpose (an attacker that compromised the secret-acceptor would be able to unseal all secrets).
* The SHSM itself must be locked down to exactly the minimum set of services required to perform the seal/unseal operation.
* Ideally, the security of the SHSM asymptotically approaches that of a real HSM; for instance, a hardware-augmented root-of-trust might be used to make it difficult for an attacker that (improbably) gains code-execution capability to instantiate their own SHSM process to decrypt secrets.
* The backend service, which might have unlimited access to the secrets stored in the SHSM, is itself a prime target of attack through clientside vulnerabilities (this is why you want to segment it off from the SHSM). Some combination of rate-limiting, anomaly detection, privilege, and user-permissions (a system might be designed to prevent the unsealing of a secret without some action having happened in the front-end within a window of time).
None of these problems are easy. You might plan on spending somewhere between 4x-10x the amount of time designing, building, verifying, and monitoring this system than you would a system doing something similarly complex with non-secret data.
If you're integrating with a financial institution that cant give u this. I'd go with paginated hash of the passwords stored in the data file with keys hashed in filed on the file system. I'd store the hash for the pages in a physical dongle attached to a server, with hardware discovery.
You could paginate the dongles daily too... There are some off the shelf dongles that do this quite nicely.