How SatoshiPay made its non-custodial Blockchain Wallet more user-friendly
It’s no secret that the Blockchain industry needs a design movement. Like every nascent industry, its space is dominated by technologists who develop too rapidly to consider the design and usability of their innovations. Conversely, because at SatoshiPay we want to offer our products to a mainstream audience, we strive to keep these challenges at the forefront of our innovation.
The SatoshiPay Browser Wallet
Our browser wallet automatically appears whenever a user enters a website that has integrated our solution (try it here). Users can then top-up the wallet with PayPal or credit cards and start purchasing content with one click.
Our core principles are:
- Users don’t have to download software or need to register
- Users are in control of their keys and we don’t have access to those keys
The private key of each user is stored in the local storage of the browser. Any time the user enters a website that uses SatoshiPay, the SatoshiPay wallet looks in the local storage for the keys to identify the user and displays the user’s balance and credentials. In other words, the key identification equals the log-in procedure.
The challenge
While this is convenient for the user, it comes with a little down-side. What happens when a user wants to apply the wallet on another browser or device? Or worse, deletes the browser history, and with it the stored keys? In these instances, the wallet and its funds will, unfortunately, be permanently lost.
The standard blockchain solution to these challenges is to ask the user to export their private key and securely store it elsewhere. To use the same wallet in a different browser, an import of the key is required.
It’s a no-brainer that this is not the most user-friendly solution. We wanted to encourage the utilization of our product by transferring these typical complexities that come with blockchain into a learned, standard usage pattern. Namely that our users should be able to simply log in with an email address and password.
For this, the user must be able to reconstruct their key with their email and password without us being able to do the same thing. The Login as a means to retrieve the private key usually consists of two phases:
- Authentication: The user provides an email address and the according password to authenticate with the server
- Private Key Reconstruction: Secret information stored on the server is sent back to the client that allows reconstruction of the private key
The Classical Login Procedure
Let us first have a closer look at the classical way to implement such a Login. For every registered user, the server stores the user’s email address as well as the hash of the password. The hashed form of the password serves for security reasons — so that the user’s cleartext passwords do not become public should a data breach occur. To further increase the level of security, one typically employs slow and salted password hash functions such as bcrypt or scrypt.
During the authentication phase, the user’s email address and password are transmitted to the server, the password is hashed and then compared to the stored hashed password for that user. If we used this classical Login for the user to retrieve their private key, then the next step would be to send back secret information to the user to reconstruct their private key. Bear in mind here that SatoshiPay could also reconstruct this key as they would also have all the required information on our servers: the user’s email address, password, and secret information. This renders the classical Login solution as a contradiction to our second core principle.
The SatoshiPay Login Procedure
For these reasons, we implemented a more powerful Login scheme. The main idea is to hash the password twice: once in the client and once on our server. Only the client-hash of the password is transmitted to our server and then (similar to the classical Login) is hashed there again. Thus our server only stores the server-hash of the client-hash of the password.
This scheme has the following two advantages:
- We have an even higher level of security as for the classical Login: in case of a data breach, the user’s passwords will not become public and the breached data does not suffice to authenticate with the server.
- We use a slow and salted password hash function for the client as well as for the server hash. For this purpose it is virtually impossible for SatoshiPay to derive the cleartext password of the user as long as it does not originate from a low-entropy source, i.e. if it is randomly generated and sufficiently long (e.g. contains at least 10 symbols).
Now the user is able to reconstruct their private key using their password and the secret information on our server whilst it still being impossible for us to do the same thing.
So what have we achieved here? We have replaced the need to remember a random 32-digit secret key with the need to remember your email and a self-chosen 10-digit password — this reduced the UX complexity dramatically, whilst we could keep the same level of security.
This is an important step in the evolution of our product and we’re looking forward to hearing your feedback. You can now sign-up after topping-up your wallet at any of our publishers’ websites. Once that’s done you’ll see your e-mail address in the panel and be able to log-out. If you’re using the wallet without backing it up with an e-mail you’ll be in “Guest” mode, meaning that you’re at risk of losing access to your wallet. Top-up your wallet at fairplanet.org to try the sign-up feature and consider donating while you’re at it ;)
___________________________________________________________________
Appendix: Technical Implementation Details
We use scrypt to hash the password in the client and we use bcrypt as the server-side password hash function. The salt for the client-side hash function is derived from the user’s email address.
The secret information stored on the server consists of:
- The salt
- The encrypted seed
- The nonce
The reconstruction of the private key happens completely in the client and comprises two steps:
- Apply scrypt again to the password and use the salt contained in the secret information
- The resulting hash is used as a decryption key to decrypt the encrypted seed. We use the stream cipher XSalsa20 together with the message authentication code Poly1305 for authenticated decryption. XSalsa20 requires the nonce for better security.
The decrypted seed is then directly used as the user’s private key.
This private key reconstruction scheme allows the user to change their email address or password while keeping the private key unchanged.
The three pieces of secret information are generated in the client when the user registers the Login.
Cost of password hash reversal
Security is always relative. So let’s have a look at the expected costs of a brute force attack to break into a single SatoshiPay user account assuming the attacker knows the user’s email address.
For a randomly generated password consisting of uppercase and lowercase letters, digits and special signs there are about 70¹⁰ different passwords of length 10.
Litecoin mining hardware (litecoin uses scrypt) can compute about 1 billion hashes per second at 1 kW [2]. The scrypt work factors used in litecoin are N=1024, r=1, p=1 [3]. We use the scrypt work factors N=16384, r=8, p=8 instead. The CPU usage grows linearly with N, r and p [4], therefore our scrypt hash function requires 1024 as much CPU work as the litecoin scrypt function. Hence, 1 kW of electric power can produce 1 million hashes per second in our case.
That means that reversing the password hash takes 70¹⁰ / 2 / 1,000,000 / 3,600 kWh on average, i.e., about 400 million kWh. If we assume 2 cents as the lower bound of the kWh price [5], then this would cost at least 400,000,000 * $0.02 = $8 million, compared to an average of $5 worth of funds in the user’s wallet.
Passwords of length 11 would cost $550 million and passwords of length 12 would cost $40 billion to reverse.
This estimate is rather low since the assumed minimal energy price is not available at this volume. We can derive a more realistic estimate by employing the hash rate in the litecoin network. The complete hash power of the litecoin network is 500 trillion hashes per second [6]. Since our work factors require 1024 as much CPU work, this translates to 500 billion hashes per second in our case. Hence, it takes 70¹⁰ / 2 / 500,000,000,000 / 3,600 / 24 ≈ 33 days on average to reverse the hash of one password of length 10 using the complete hash power of the litecoin network. At 14,400 litecoins mined per day [7] and a $95 price per litecoin [8], this equals a total mining reward of 33 * 14,400 * $95 ≈ $45 million. Assuming that the litecoin mining market is efficient, the energy cost — and therefore the cost to reverse the password hash — would have the same order of magnitude.
[1] Bernstein D.J., van Gastel B., Janssen W., Lange T., Schwabe P., Smetsers S. (2015) TweetNaCl: A Crypto Library in 100 Tweets. In: Aranha D., Menezes A. (eds) Progress in Cryptology — LATINCRYPT 2014. LATINCRYPT 2014. Lecture Notes in Computer Science, vol 8895. Springer, Cham
https://tweetnacl.cr.yp.to/papers.html
[2] https://coincentral.com/best-litecoin-mining-hardware/
[4] https://blog.filippo.io/the-scrypt-parameters/
[5] https://www.globalpetrolprices.com/electricity_prices/
[6] https://bitinfocharts.com/comparison/litecoin-hashrate.html