How to store RSA private keys in the client's browser for better UX?

I am planning on writing a web-based password management software, in order to provide sharing and permissions functionalities within team groups and members.

EDIT:

As mentioned below by Luke Park, I wanted to add that I am using a user-password authorisation with tokens (which expire). The token is provided on all authorised API calls making these calls only accessible by registered users. And yes, the application is wrapped by SSL making communication between server and client more secure.

END OF EDIT

Currently I have done a lot of research about finding a correct pattern for handling password encryption. The pattern that I am looking at is called Hybrid Encryption since it works with multiple clients and can be implemented securely. Here's how I would implement this pattern in my application logic:

CLIENT WANTS TO CREATE A PASSWORD

  • Andre creates a password and provides the password as plain text
  • The frontend app generates a symmetric key which is called session key
  • The client encrypts the plain password with the session key
  • Andre chooses to share the password to Bob
  • The client retrieves the Bob's public key from the server application via REST
  • The client encrypts the session key with Bob's public key
  • Client transfers the encrypted session key and the encrypted password to the server
  • SERVER APPLICATION HANDLES PASSWORD SUBMISSION

  • The server application encrypts the data with a private salt, which is only known by the server application
  • Sever stores the data into a database
  • RETRIEVING SHARED PASSWORDS

  • Bob requests Andre's recently shared password
  • Server decrypts the requested dataset with the private salt and sends it to the client
  • The client decrypts the session key using Bob's private key (which is provided by Bob's computer)
  • Using the decrypted session key, the client can decrypt now the password (Now it can be copied for example)
  • So far, I see this pattern secure enough, since all private keys of the clients are not public and only visible to the clients. In order to implement this in a web-based application, I found openpgpjs.org which can generate public and private keys on client side and encrypt or decrypt data aswell using these keys. On top of that, private key strings can be protected by a secret passphrase.

    My question is, how can I implement the private key file into my frontend application without messing up the user experience? I don't want to force the user to manage his private key manually and force him to provide the key on each password request. Is it secure to store the private key file into the browser's local storage and get the private key from local storage on each password request?


    You still have no way to verify your clients and server. Because anyone can publicly request public keys, it would be easy to MITM between a client and the server, and feed it a garbage arbitrary password.

    Consider:

  • Attacker retrieves Bob's Public Key using REST.
  • Attacker generates their own "Session Key" and encrypts some arbitrary value.
  • Attacker feeds the result to the client, who has been Man-in-the-middled.
  • Client thinks it has received the correct password, but hasn't.
  • Without being able to verify and authorize both server and client, your system becomes easy to mess with. It may not seem like a huge problem, but it can easily make way for other attacks.

    EDIT: Also noticed that if a MITM occurs between the client and the REST API, the attacker can feed the client a public key paired with a private key that the attacker owns.

    Consider:

  • Client is about to share it's password with the server.
  • Client contacts the REST API (MITM Attacker) to pull Bob's Public Key.
  • Attacker supplies their Public Key.
  • Client generates Session Key and the ciphertext of the password.
  • Client sends the result to the "server" (the attacker).
  • Attacker uses their Private Key to retrieve the Session Key.
  • Attacker uses the Session Key to retrieve the plaintext password .

  • After a couple of thoughts I decided to encrypt the RSA private key with the user master password. Since the master password is nowhere stored, I assume that it is safe to store the encrypted private key into the user's local browser storage. This solution makes it possible to automatically provide the encrypted private key on each password request, but forces the user to enter his password on each request, which is fine for me for now.

    If anybody has a better solution, I would be glad if you can post your solution here.

    链接地址: http://www.djcxy.com/p/21776.html

    上一篇: 将公钥/私钥安全地存储在数据库中

    下一篇: 如何将RSA私钥存储在客户端的浏览器中以获得更好的用户体验?