It’s an exciting time: you want to get your users on board with Web3! Luckily, there’s a cornucopia of embedded wallet products with seamless social login and smooth UX. How do you choose?! If you’re looking for an embedded wallet that will keep your users’ keys safe—and keep you safe from key custody risk—read on.
<br>
__Here are the four questions to ask before choosing your embedded wallet provider.__
<br>
## 1) Where and how does the wallet sign transactions?
<br>
When your users move assets, swap tokens, or buy NFTs, your embedded wallet has to sign transactions that represent those transfers or swaps. There are three general <a href="threat-modeling-for-web3-key-management" target="_blank">approaches to signing</a>:
<br>
<ul>
<li><a href="why-you-should-never-handle-private-keys-in-the-browser" target="_blank">Signing in the browser</a>. Each time the user requests a transaction, the embedded wallet retrieves or reconstructs their key, pulls it into the web browser, and signs. This is risky because browsers are an adversarial environment—everything from browser extensions to malicious ads can try to steal your key. Any imperfection in the massive browser codebase or wallet codebase means game over—and there are many imperfections. I, your friendly blog post author, made extra money in grad school by finding and reporting exploitable browser security bugs.
<br>
And, while exploiting browser bugs is tricky, exploiting bugs in JavaScript wallets is straightforward: it’s almost impossible to convince the JavaScript language not to leak secrets. So: unless you have a good excuse (and you probably don’t), avoid browser-based signing.</li>
<li><a href="mpc-does-have-a-single-point-of-failure" target="_blank">Signing as a multi-party computation (MPC)</a>. An MPC wallet splits keys into multiple “shards” held by different parties (e.g., your users and the embedded wallet provider). Then, some number of parties (e.g., ⅔) can jointly produce a signature without revealing their shards to one another—or to attackers. In theory, MPC wallets never instantiate the entire plaintext key, which is great! In practice, MPC is bleeding-edge cryptography that’s hard to get right, and we’ve seen numerous bugs in complex MPC codebases lead to key compromise.</li>
<br>
<li><a href="intel-sgx-is-broken-again-what-the-downfall-attack-means-for-secure-hardware" target="_blank">Signing in secure hardware</a>. Since essentially all known key extraction attacks on Hardware Security Modules (HSMs) require physical access to the HSM itself (and advanced tools like electron microscopes!), signing in secure hardware is a gold standard for keeping keys safe from attackers. Banks have used secure hardware as the foundation of their security model for decades. Not all secure hardware is created equal, though: for example, Intel’s SGX has a long history of serious bugs, so make sure to ask follow-up questions about the specific hardware, its track record, and its guarantees.</li>
</ul>
<br>
## 2) Where and how are the private keys stored?
<br>
When your users aren’t using their wallet, their keys still have to live somewhere. There are two key storage axes: where the keys are stored (e.g., on the wallet’s servers or the end-user’s phone), and how the keys are stored (e.g., shared or encrypted). Figure out if your embedded wallet stores keys:
<br>
<ul>
<li>As plaintext (i.e., not encrypted) on...
<ul>
<li>…the wallet’s servers. This is extremely dangerous. Your embedded wallet provider and any attacker who compromises that attacker can steal your users’ keys.</li>
<li> …the end-user’s device. This is also dangerous. Anyone who steals or hacks your users’ e.g., phones can access their keys.</li>
</ul>
</li>
<li>Encrypted on...
<ul>
<li>...the wallet’s servers. Figure out who can decrypt them (the embedded wallet provider?) and where they exist in decrypted form (the browser?).</li>
<li>…the end-user’s device. Once again, determine when and how the keys can be decrypted. Also ask what happens if the user loses their phone or laptop: are the keys gone forever?</li>
</ul>
</li>
<li>Sharded (i.e., in pieces) on the wallet’s server and the end-user’s device. That means that, instead of storing entire keys, the embedded wallet stores the key in several pieces—making it harder for an attacker to steal. Check how the shards are stored; for example, storing every shard unencrypted in the same database defeats the purpose of the sharding. Also check how the shards are used during transaction signing: if they’re stored in different locations and then pulled into the (more vulnerable) browser in plaintext, an attacker can pull off a browser attack to reconstruct and steal the key. Finally, ask what happens if the user loses the device that holds their key shard. Do they lose access to their key forever? If not… maybe the way the shards are stored isn’t quite as advertised.</li>
</ul>
<br>
## 3) Is the wallet _actually_ self-custodial?
<br>
Once you know how private keys are stored, you can determine if the wallet is self-custodial—regardless of what its marketing says. In a self-custodial wallet, there should be _no way_ for the service operator to access end-user keys.[^1] Here are three scenarios to consider:
<br>
<ul>
<li>If the embedded wallet provider stores plaintext keys server-side, they can access those keys. You shouldn’t use this provider (for a whole host of reasons).</li>
<li>If the embedded wallet provider stores encrypted keys server-side, ask what mechanism prevents them from decrypting those keys. It should be more than good will or hand-waving about fancy cryptography. If the embedded wallet provider shards keys, ask how cross-device access and key recovery/backup work.</li>
<li>If, for example, your user can create a wallet on their phone and immediately access that same wallet on their computer, there’s a problem: how does their computer access the shard from their phone? Most likely, this implies that the embedded wallet provider stores a complete copy of the key somewhere on their server.</li>
</ul>
<br>
## 4) Who wrote the cryptographic code and the system around it?
<br>
Every undergrad security class repeats the same refrain: “don’t roll your own crypto.” Writing cryptographic code is so hard because of a fundamental asymmetry introduced by the adversary: the adversary wins if there’s a single exploitable bug, while the defender only wins in the absence of _all_ bugs. Worse, cryptographic algorithms are delicate creatures; even small timing variations in algorithms’ execution can leak entire secret keys.
<br>
So check out your embedded wallet provider’s _About_ page. Ideally, the team should include an applied cryptographer who has years of experience implementing (both Web2 and Web3) crypto code, _and_ engineers who have shipped security-critical systems before.
<br>
Check out <a href="/about" target="_blank">our About page</a> before heading to <a href="/cubesigner-hardware-backed-wallet-as-a-service-for-non-custodial-end-user-wallets" target="_blank">our Wallet-as-a-Service page</a>!<br>
<pre>
<br>
<br>
</pre>
[^1]: If _you’re_ providing a self-custodial service, in turn, the embedded wallet provider should also give a coherent technical explanation for how it can ensure that your service stays non-custodial. <br>