You may want to consider using the Web Cryptography API for client-side cryptography in the web browser. Then, you can create a keypair using the webcrypto api, and store the CryptoKey object, containing the user's private key, with the .extractable property set to false, using Indexed DB storage. This way the private key can only be used for decrypting and/or signing messages within the browser - but can not be read (even by client-side scripting in the browser).
For more info, see:
- https://pomcor.com/2017/06/02/keys-in-browser/
- https://www.w3.org/TR/WebCryptoAPI/
- https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
- https://www.w3.org/TR/IndexedDB/
- https://www.boxcryptor.com/en/blog/post/building-an-app-with-webcrypto-in-2016/
- https://gist.github.com/saulshanabrook/https://gist.github.com/saulshanabrook/b74984677bccd08b028b30d9968623f5
- https://blog.engelke.com/2014/09/19/saving-cryptographic-keys-in-the-browser/