Securely Creating and Storing Cryptographic Keys in the Browser

2022-12-21
2 min read

This post is mostly a reference to another demo you can find here.

In this post, I’ll look at securely creating and persisting public/private keys in the browser. The linked demo shows how we use a key pair generated with WebCrypto to sign and validate a JSON Web Token(JWT) completely in the browser.

The cool thing about using the CryptoKey interface of WebCrypto API is that it allows developers to interact with key pairs generated in the browser - you can sign, verify, encrypt, and decrypt - without revealing the value of the private key. The private key remains opaque to the end-user and the JS runtime. Developers can work with the CryptoKey interface directly without having to worry directly handling the underlying keys.

We can store this CryptoKey object in IndexedDB for later retrieval and use. Because we can persist the CryptoKey, we can do things like continuously sign JWT’s with the same private key over multiple browser sessions (until browser storage is cleared). This can be handy for some use cases like OAuth2’s Dynamic Client Registration Protocol.

See the code behind this demo

Demo

In this demo, you should see a JWT being signed and validated using public/private keys generated with the WebCrypto API as you click on the buttons below. The generated CryptoKey is stored in IndexedDB so we can reuse the same key pair over multiple browser sessions.

Note you need to have SSL enabled for this demo work - WebCrypto is disabled in non SSL environments.

Go to demo here