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)
Last but not least, every time you login, you are given a SessionKey that enables you to perform any function like editing or creating new data. This SessionKey rolls after every action. So, on login you get S1, then you make a new piece of data and S1 is deleted and S2 is given to you. So on and so forth. Each SessionKey has a one hour time limit as well. Here's my data structure for that:
// SessionKey
- Key (32-bit GUID)
- HashedUser
- ExpirationDate
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. My question to the community is - what am I doing wrong? No crypto implementation is being rolled by me, I'm just using multiple stock implementations. BCrypt is 10 rounds and PBKDF2 is 20,000 right now. Are those high enough for contemporary cryptography and the computer systems I know some people have? Are there any gaping holes? Is the whole thing wishful thinking?
Username
cannot be a hash, let alone a hash of ausername
, etc.. $\endgroup$