6
$\begingroup$

I understand that non-extractable keys are secure because they cannot be exported. But I think many people would WANT to export their keys at some point if they don't want to risk losing everything.

For example, if you stored all your app data encrypted using a WebCrypto non-extractable key and can't export the key, this means you lose access to all your encrypted data when your indexedDB gets wiped out for some reason, or even worse, if your entire computer gets wiped out or the disk gets corrupted (This is not an impossible scenario. For example when you send off your problematic macbook to Apple for repair, they say I should back up everything in case something goes wrong)

This is just encrypt/decrypt scenario, but I'm sure there are same types of issues with sign/verifying messages. If I want to use crypto as my identity by signing messages, why would I want to use a key that even I cannot access and export myself, so I can only use that key on that specific browser on that specific device?

So I guess this is a four part question:

  1. What are the actual use cases for non-exportable keys? Why would people want to go that far while risking key losses?
  2. Don't most people want to be able to reuse and back up their keys, especially since they're used for identity and encryption purposes?
  3. If #2 is true, and there is no way to securely store extractable keys inside a browser, how do people build a secure app using WebCrypto?
  4. Finally, isn't storing keys on the browser fundamentally insecure whether extractable or not? Even if the key cannot be exported, a website sign a message on behalf of the user (or decrypt a message intended for the user and send it to their server) without the user knowing, and that's a huge security issue.
$\endgroup$
2
  • 1
    $\begingroup$ My understanding of the WebCryptoAPI is that it specifies that the key is non-extractable thru the API: any attempts at that must end in InvalidAccessError. I don't see that it implies that the key is not exportable (e.g. by the user of the web browser). Anyway, that level of un-exportability is weak or requires secure hardware that's not available on many standard computers/OSes, much less is used by standard web browsers. $\endgroup$
    – fgrieu
    Oct 15, 2020 at 16:41
  • $\begingroup$ Just a note that public key is always extractable. So that might be enough for many use cases. $\endgroup$
    – Mitar
    Dec 4, 2023 at 20:59

3 Answers 3

2
$\begingroup$

The DPoP extension in OAuth 2.0 for binding issued tokens to a private signing key belonging to an SPA client is a use case that benefits nicely from non-extractable keys.

If the private key gets lost the client will need to reauthenticate the user and ask for their consent again, which is a desired effect.

https://datatracker.ietf.org/doc/html/draft-ietf-oauth-dpop-03

$\endgroup$
2
$\begingroup$

The best thing about non-extractable keys it that they are literally the only thing on the web which the web server cannot compromise. The web server can easily change up your Javascript code, to steal anything that resides in IndexedDB. It can read all your cookies. It can even serve Javascript that will grab the non-extractable key from the IndexedDB and sign something with it (including through a silent Web Push + Service Worker in some browsers). But it can't grab the key itself. So if you're not running the site or service workers in the browser, then you aren't signing anything.

That's still a lot of security exposure. So what non-extractable keys are really good for is Browser Extensions, or where site A (which you trust, because maybe you are running open source software on the web server yourself) is used to sign transactions on all other sites. The Browser Extension or Site A stores a non-extractable key in its IndexedDB, and no other site can even abuse it to sign with. And if your web server is compromised, the key is still safe.

Actually, being able to export your private keys opens a pandora's box of security vulnerabilities. Almost every time you hear about someone's Ethereum account being "hacked", it's probably because they entered their private key, or the mnemonic (12 word phrase) that generates it, into some website somewhere, or wrote it down in a place someone else found it.

Look at how KeyBase does it, and other secure messengers. Your private keys never leave your device. If you want, you can provision sessions on other devices by signing a certificate (that's what happens when you scan a QR code somewhere).

Assuming the user agent (wallet, browser) is secure and doesn't betray the user, the second most common way people's keys can be compromised is a "session fixation attack": having the key or phrase be generated by some website (e.g. for vanity addresses) and the user agreeing to use it as their address, subsequently transferring a bunch of valuable assets to that address.

$\endgroup$
1
$\begingroup$
  1. What are the actual use cases for non-exportable keys? Why would people want to go that far while risking key losses?

One of the main ideas of key stores is that access to the keys is minimized; as long as you don't export a key, you can be sure that no other service is using the key.

  1. Don't most people want to be able to reuse and back up their keys, especially since they're used for identity and encryption purposes?

That depends.

Private keys used for decryption you may want to be backed up. Note that the term "exportable" is probably taken from PKCS#11 used for HSM's and Smart Cards. And note that HSM's do often allow for secure backup, e.g. to another HSM.

As for signature generation: consider losing a smart card with a single key. In that case you may simply request a new card. The signatures can still be verified as long as the public key is available (and not revoked because the private key has been compromised).

  1. If #2 is true, and there is no way to securely store extractable keys inside a browser, how do people build a secure app using WebCrypto?

I'm not sure about that. I must say that I find WebCrypto a pretty ill thought out API. To be honest, I think they just copied the exportability part from PKCS#11 / cryptoki.

  1. Finally, isn't storing keys on the browser fundamentally insecure whether extractable or not? Even if the key cannot be exported, a website sign a message on behalf of the user (or decrypt a message intended for the user and send it to their server) without the user knowing, and that's a huge security issue.

The main issue with WebCrypto is establishing trust with the browser; that's nigh impossible even for the server providing the code and pages. Still, you could use it to encrypt with a public key. That could provide some protection against passive attacks against a past TLS session, for instance.

$\endgroup$
5
  • $\begingroup$ Thank you. Could you elaborate a bit more on this part?: "The main issue with WebCrypto is establishing trust with the browser; that's night impossible even for the server providing the code and pages. Still, you could use it to encrypt with a public key. That could provide some protection against passive attacks against a past TLS session, for instance." ==> Are you talking about the server stealing the user keys? And that you protect against it by encrypting? How does this encryption work for example? $\endgroup$
    – Vlad
    Oct 17, 2020 at 14:11
  • $\begingroup$ No. Generally using JS based crypto is insecure because a man-in-the-middle could (for instance) could interfere with the application code and generate a key pair themselves, leaving the users with a false sense of security. However, if you assume that the initial TLS connection remains secure, you could still use it for application level security, e.g. over various TLS connections where eavesdropping of the plaintext is possilble. E.g. you could have a cloudflare service decrypting your traffic for protective services. $\endgroup$
    – Maarten Bodewes
    Oct 17, 2020 at 14:17
  • $\begingroup$ "Generally using JS based crypto is insecure because a man-in-the-middle could (for instance) could interfere with the application code and generate a key pair themselves" ==> If a man in the middle interferes with the code and generates a keypair himself, doesn't this keypair have nothing to do with the keypair the end-user (me) creates? For example, if I create a WebCrypto RSA-OAEP keypair, and a "man in the middle" generates his own RSA-OAEP keypair, these two keys are completely separate as far as I understand, how can the man in the middle can mess with my encryption/signatures? $\endgroup$
    – Vlad
    Oct 17, 2020 at 14:31
  • 1
    $\begingroup$ No, not really, they can be stored as local data which is normally specific to a site, as far as I can tell. There is an interesting page with use-cases which gives some ideas how keys can be used. $\endgroup$
    – Maarten Bodewes
    Oct 17, 2020 at 16:42
  • $\begingroup$ @Vlad You might ask for a non-exportable key, but the browser might've been modified to export all the keys to disk anyway. $\endgroup$
    – user253751
    Mar 4, 2021 at 16:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.