Note: You are viewing this blog post without the intended style information, which may result in formatting issues.
It recently came to my attention that John McAfee has been advertising a cryptocurrency hardware wallet from a company called Bitfi, with the claim that it is "unhackable". There's even a $250,000 bounty to hack it. I do not have one of the actual devices in my possession, but from my review of the publicly available "source code" [PDF] and their private key calculator, my conclusion is that their product is most charitably described as a "footgun".
Quoting McAfee (who is known for promoting scams),
For all you naysayers who claim that "nothing is unhackable" & who don't believe that my Bitfi wallet is truly the world's first unhackable device, a $100,000 bounty goes to anyone who can hack it. Money talks, bullshit walks. Details on Bitfi.com
We created a simple, foolproof way to use the brain as the wallet. The Bitfi.com wallet is the transcriber between the inner brain and the outer world of digital currencies. Until someone discovers a means of hacking the brain, your money is safe.
Oh, dear... That sounds terribly familiar. In the lead-up to my talk about cracking these kinds of schemes, Wired published an article about my work literally titled "Brainflayer: A Password Cracker That Steals Bitcoin From Your Brain". My talk managed to kill the infamous brainwallet.org site, but the idea of turning a user supplied passphrase into cryptocurrency keys seemingly will not die. I had to take a look at what Bitfi was actually doing.
To start with, I had a look at their their bounty offer:
This bounty program is not intended to help Bitfi to identify security vulnerabilities since we already claim that our security is absolute and that the wallet cannot be hacked or penetrated by outside attacks. Rather this program is intended to demonstrate to anyone who claims or believes that nothing is unhackable or that they can hack into the Bitfi wallet, that such attempts are futile and that the advertised claims about the Bitfi wallet are accurate.
In other words, the sole purpose of it is to discredit security researchers like myself who raise concerns about the design of their product. This is not a new trick — it was specifically called out by Bruce Schneier as a red flag nearly twenty years ago. In this instance, Bitfi is calling it a "bounty program" to try to ride on the coattails of legitimate bug bounty programs, which are generally wide in scope. This one is unfair, falling into exactly the pattern that Schneier described:
Most cryptanalysis contests have arbitrary rules. They define what the attacker has to work with, and how a successful break looks. Jaws Technologies provided a ciphertext file and, without explaining how their algorithm worked, offered a prize to anyone who could recover the plaintext. This isn't how real cryptanalysis works; if no one wins the contest, it means nothing.
Indeed, you have to be spend $120 on a Bitfi device, and then pay another $10 to "preload it with coins" to even try, and then you specifically have to hack the wallet associated with particular the device they send you. If a researcher found, for example, the device had a weak RNG that allowed for key recovery by examining a series of transactions generated by it, they would not win the bounty. Neither would they for finding a way to hijack their automatic update system to install a keylogger.
Another point Schneier makes is that often the details of the algorithms used in these sorts of contests are often kept secret:
Most contests don't disclose the algorithm. And since most cryptanalysts don't have the skills for reverse-engineering (I find it tedious and boring), they never bother analyzing the systems.
Kerckhoffs's Principal in essence says that a properly designed system should still be secure even if the attacker knows everything except the key. Here, Bitfi engages in some misdirection, claiming to be "open source", however their "source code" is just a PDF largely made of formulas copy/pasted from the description of scrypt and BIP32. A number of people called them out on this, and in response a comment on reddit, a user going by Bitfi-Team replied:
We never said we were providing full open source code. We clearly state that our wallet is open source. Just check our website before you spew garbage. But if you want the code, do some math. Don't be lazy.
Not inspiring confidence. The PDF does not acknowledge that they're using anything related to scrypt or BIP32, and I had to compare the formulas to verify. Algorithms 5 and 6 in the paper are not clearly described, and for a full understanding I had to resort to decompiling their private key generator tool which was inexplicably hosted on the site of a juice company. The zip included two DLL files and a Windows executable, which turned out to be a .Net console application written in C#. Despite it having been run through an obfuscator, dotPeek was able to give me a good picture of what was going on.
The tool displays a dire warning with a scary red background when first started:
WARNING!!!! Entering your information on this computer is extremely unsafe and it is very possible that you will lose your money by running this application.
Enter Y to continue or any other key to immediately exit and close this program.
If you're brave enough to enter
Y at this point, it will prompt you to
enter a code for the cryptocurrency you're using, the address you want to
recover the private key for, your "salt" (a user selected value, they recommend
using your phone number, social security number, or email address) and
passphrase. The private key will only be printed if the address matches, but
that restriction is not inherent in the algorithm. After a few hours, I was
able to get a compatible implementation in Python.
It's essentially BIP32. with a few modifications (the string "Bitcoin seed" is replaced with SHA256(salt), which is not mentioned in the PDF) and scrypt(pass, salt, N = 217, p = 4, r = 8, dkLen = 64) to seed the master key. Currency specific subwallets are derived with the BIP32 hardened CKD function using a "creative" algorithm to generate the subkey id. Again, I don't have a physical Bitfi device, so I can't verify the device itself follows the same algorithm, but this is compatible with the software they have publicly available.
Since publication, another researcher has been able to verify that the device generates addresses and keys matching my scripts.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
import sys import hmac import hashlib import scrypt from pybitcointools import * def ci(s): acc = "" for c in s.upper(): acc += str(ord(c)-64) return int(acc) def print_address(k, password, salt, coin): priv = decode_privkey(k, 'hex_compressed') pub_c = privkey_to_pubkey(priv) pub_u = encode_pubkey(decode_pubkey(pub_c), 'hex') addr_u = pubkey_to_address(pub_u) print "Y\n%s\n%s\n%s\n%s\n\n" % (coin, addr_u, salt, password) def derivekey(password, salt, coin, n): k_par = scrypt.hash(password, salt, N=32768, p=4, r=8, buflen=64) c_par = hashlib.sha256(salt).digest() param = hmac.new(c_par, k_par, hashlib.sha512).digest() (msk, mcc) = (param[0:32], param[32:64]) master_key = bip32_serialize((PRIVATE, 0, b'\x00'*4, 0, mcc, msk+b'\x01')) coin_key = bip32_ckd(master_key, ci(coin) | 0x80000000) sub_key = bip32_ckd(coin_key, n) # ** test comment please ignore return bip32_extract_key(sub_key) if __name__ == "__main__": (p, s, c, n) = (sys.argv, sys.argv, sys.argv, sys.argv) priv = derivekey(p, s, c, n) print_address(priv, p, s, c)
Security-wise, this is about on par with using WarpWallet to generate a seed for a BIP32 wallet. Anyone can download the relevant blockchain and use something similar to brainflayer to search for weak passphrases across all addresses simultaneously. A patch adding support for Bitfi should be out in a few weeks after I recover from DEFCON (I'm helping run a legitimate hacking competition). I also note that Bitfi is using uncompressed keys, which result in unnecessarily large transactions and have therefore been deprecated for several years.
For savvy users who make no mistakes, this may provide adequate security. There are a few problems, though. First, despite Bitfi providing some reasonable advice on passphrase selection, somebody is bound to pick something obvious. Second, it is highly impractical to change one's passphrase once in use since all addresses are derived from it. Third, this product design has a failure modes that most hardware wallets do not — cryptocurrency thieves can rob users who choose weak passphrases without needing to steal the hardware wallet first. Bitfi tries to sell this as a feature — "If the device is seized or stolen, taken apart and forensically analyzed the private keys cannot be retrieved". This statement seems to follow from the claim that the device never writes any key material, even encrypted, to persistent storage. Perhaps true technically, however as I mentioned above, the consequence of this design is that cracking attempts do not require the device. The entire security is dependent on a single factor — "something you know" rather than the two factor security provided by typical hardware wallets — "something you know, plus something you have".
I strongly advise against using one of these devices. While Bitfi is perhaps not an outright scam, the design is inferior to that of hardware wallets where the device really is needed (or the backup of the seed) along with the passphrase in order to spend the coins. The fact that they're using a lot of the same techniques to sell devices that have been used to sell snake oil so many times in the past makes me very concerned. I've notified Bitfi of these issues, however they showed no interest in fixing them.
Shortly after the original publishing of this post, @sshell_ discovered that Bitfi's CEO, Daniel Khesin, had been in a legal fight with DS Healthcare. From a closer examination of the documents, it looks like the court ruled in Khesin's favor.
I wrote this post simply to explain the risks of the Bitfi's product to people who might be harmed by it. Unfortunately, I now need to address accusations by some individuals affiliated with Bitfi that this article is retaliation for them turning me down for a job. To be clear, the tweet in which I said "contact me via email if you're interested in hiring me to do a security evaluation" was not a request for employment, merely a tactic to shut down the conversation. I already have a full time job and various side projects that keep me too busy to take on paid consulting work.
While I'm at it — I have no financial interest in any cryptocurrency wallet. My blog is operated at a loss without ads, coinhive, or any other monetization scheme. This post and the work behind it was not sponsored or approved by my employer. It was written without compensation or expectation thereof. I respond to such offers by posting screenshots.