Say I want to create a cloud based private key storage for users, which they can use to sign documents.
On the server side I would use a HSM to make the key storage more secure.
One option is that the signing happens on the server side. But, this way the server knows the private key of the user, which is not what I would want.
Another option is to have the user's private key wrapped in an symmetric key (for example AES) only known by the user, and store it on the HSM.
This AES key would be derived from the user's password. There are mechanisms like PBKDF2 to create a key from password.
Then, when user requests to sign a document, the server would send that users's private key encrypted by the AES key only known to that user.
The client side(which could be an android app, or webapp based on javascript) is used to make a signature.
Also, there would need to be a password change mechanism which would function something like this:
- client requests his private key from the server(encrypted by his AES key)
- client decrypts the private key usign AES key derived from his password
- client generates a new key using his new password
- client encrypts his private key with his AES key and sends it to the server
- server updates the wrapped user's private key with the new one
I don't know much about the HSM modules, but as I understand they have a similar functionality as a smart card( the key sould never leave the HSM and all the encryption should happen on it).
I read somewhere that some HSM's allow key extraction when PKCS#11 "CKA_EXTRACTABLE" is set at time of a key generation. But, wouldn't that, for the most part, defeat the sole purpose of the HSM.
Also, would I be able to implement the mechanism for password changing I described when using a HSM?
Another option would be that the signing happens on the HSM, and the private keys are wrapped by the AES key, generated from the user's password. HSM then unwraps the private key and sign the file, but the private key itself cannot be accessed by the cloud provider.
Would, in this case be possible to implement the password change mechanism I described?
Also, password-based key derivation mechanisms use salt to make rainbow table attacks more difficult.
How would salt be used in this case? Would it be stored on the server and then transferred to the client when using the service?
The requirement is that the user can use the service on any device(mobile, desktop) only knowing his username/password.
I would probably include 2FA by adding SMS verification when authenticating to the server.