Ask HN: What's wrong with my security model - and where can it be attacked?

6 points by bennyg ↗ HN
I'm working on a little personal project where security is very important, and I've thought for a while about the best way to do this. Now I am looking for a little outside help on good practices. The goal is to store personal text data on a server (like wifi passwords, etc) and be obtained through a password. I wanted to make user accounts for a few friends so that we each could securely store text snippets and retrieve them without the others knowing them. Here's my data structures:

  // Account
  - Username
  - Password
  - Salt

  // StoredData
  - Title
  - Info
  - User
Okay, now the fun part. Here's how I'm obfuscating the data. When a friend creates an account, their username is salted with a salt in the server config files (this is Rails btw, so ENV['SALT']) and then SHA256'd. The password is generated via BCrypt. The only thing I'm not sure about are how many rounds to do for BCrypt so the server stays snappy; right now it's at default for ruby's bcrypt library. A random salt is also saved in the Account for the next step.

  Username = SHA256(username + SERVER_SALT)
  Password = BCrypt(password)
  Salt = BCrypt.generateSalt
When a friend saves their data, it is encrypted using AES-256. So for this, an AES Key is generated using a combination of their plaintext username and password, as well as the salt generated in Account creation. That key is never stored on the server, but created on device at runtime.

           PBKDF2_HMAC_SHA1(secret, salt, rounds)
  AESKey = PBKDF2_HMAC_SHA1((usernamepassword), Account.Salt, 20000)
  Title = AES-256(AESKey, title)
  Info = AES-256(AESKey, info)
Also, the whole thing is sent back and forth over SSL, though after the recent revelations I'm not too sure how secure that is anymore.

HN, what did I mess up?

2 comments

[ 1.6 ms ] story [ 14.6 ms ] thread
2000 character limit, so here's the rest:

My first thoughts are on SSL - if that's secure enough. Because usernames and passwords hit the backend code in plaintext, and then are transformed, a MITM attack that knows my ssl key could render it useless. Another thought is that if someone knows another's user/pass, they get access to everything - but that's kind of unavoidable.

The whole goal is to never save anything as plaintext either. So that's why the username is SHA256'd, and the password is Bcrypted, and the data is AES256'd.

(comment deleted)