I'm designing an API in PHP/MySQL that, by its design, will not store a user's password in the database and thus does not generate authorization tokens for the client to hold. The reason for this is to prevent any possibility of sensitive, unencrypted information being obtained in the event of a database compromise.
The user's sensitive data is encrypted using their own password, so that the decryption of the data cannot be done with anything stored within the (potentially compromised) database. I've implemented some security features currently:
- As previously described, the sensitive data is encrypted using AES using the user's SHA-512 hashed password (the password is provided with every request as form data), plus some extra salt.
- HTTPS is required, and only POST requests are permitted.
- User accounts are identified by e-mail addresses (trimmed and lower-cased in storage) and require verification before use.
- User passwords are required to be a minimum of 8 characters long.
- Eventually, an API token will be required for third-party app usage via the Authorization header. Third-party apps are restricted in that they cannot create, verify or delete accounts.
My question is, is this enough? I'm hardly a security expert and the last thing I want to do is design something with a major oversight. My main concern is the user's password being provided with every request, even though it would be only through SSL.
To clarify, users will be able to change their passwords provided they still have their current one. A request is made containing the user's e-mail address, the current password, and the new password. The request is authenticated like it normally is, using the e-mail address and the current password. Validation is done on the new password (enforcing the 8-character minimum) as well, before continuing.
First, just as it's done when the user wishes to retrieve their sensitive information, the information is decrypted using their current password. In its decrypted state, the information is then encrypted using the new password, and the sensitive data is overwritten in the database.
At this point, there is no stored record of the previous password and it can no longer be used. A password change cannot be done by an administrator or, in any case, without the password that was used to previously encrypt the information. If the password is lost, then nothing can be done.