Closed GoogleCodeExporter closed 9 years ago
Enhancement for ECkey generation and storage
In the current implementation of bitcoinj, wallet files containing private keys
are saved on a file system. Would there be some way in future that ECKey
private keys could be imported from external secure storage like smart cards
and secure elements in android environment.
From conversation on
http://code.google.com/p/bitcoin-wallet/issues/detail?id=228, got information
that the ECKey implementation might be refactored in the near future to support
BIP32 HD wallets. I would like to ask lead developers of bitcoinj if they would
consider to provide an interface to access and store parent keys in external
secure storage instead of wallet files.
of course importance of using smart cards or secure elements for bitcoin system
is far more than the point i stated above.
Would be so glad hear from everyone interested on the topic
Original comment by mytrial4@gmail.com
on 29 Sep 2013 at 9:36
It is not possible, nor would it be useful even if it was possible.
Android *does* support storing private keys into hardware key stores that are
inaccessible even to the OS kernel, since Jellybean MR2:
http://developer.android.com/about/versions/android-4.3.html#Security
It's exposed via the standard Java crypto APIs. However, it isn't helpful for
Bitcoin because:
1) Keys are never exported from the secure element, and thus have to be
generated and manipulated by the hardware itself. Ignoring the possibility of
NSA backdoors, there is a more practical problem - Bitcoin uses an elliptic
curve that's very unusual, and which is not a part of the NIST standards. Thus
it's extremely unlikely that any secure element will support such keys.
2) BIP32 HD wallets require some custom elliptic curve maths to be done on the
private keys in order to do the derivation. Because the whole notion of HD key
trees is something invented by the Bitcoin community, the hardware won't
support that either.
3) Even if the secure elements and APIs supported everything we wanted, the SE
would end up having to sign whatever the host OS wanted it to anyway, making
the whole thing pointless. Bitcoin keys aren't like keys used for securing
communication. Private keys used for encrypting communication can be stolen and
used secretly to spy on people, and that's useful. But a stolen Bitcoin private
key is useful only for grabbing the users money, which is an inherently public
act. There's therefore no benefit to keeping the private key behind a device
that will sign any message it's given, whilst still keeping the private key
safe.
Fortunately, all is not lost. The Trezor device is a small piece of hardware
designed specifically for the Bitcoin communicaty that solves all these
problems:
1) Trezor can work with secp256k1 because it's just a general mini computer,
not a dedicated piece of crypto silicon.
2) Trezor supports HD wallets natively.
3) Trezor has a display and a couple of buttons which can be used to confirm to
the user what it's about to sign. Thus even if malware or a hacker compromises
your phone, it can't submit bogus requests because the user won't (shouldn't)
confirm it.
The Trezor is tiny, it's small enough to fit on a key ring, despite the screen.
Trezor support is being implemented in Java by Gary Rowe and Jim Burton for
MultiBit. It communicates as a USB HID device, and most Android devices these
days can act as a host:
http://developer.android.com/guide/topics/connectivity/usb/host.html
So Trezor support for the Android wallet app shouldn't be very hard to do - it
essentially means glueing TrezorJ to the Android USB API and then implementing
the UI support for it.
Original comment by hearn@google.com
on 30 Sep 2013 at 8:48
As far as I am aware (and I might be wrong, so please feel free to correct me),
the hardware-backed key store in Android relies on TrustZone in the current
implementations and does not use a secure element. The security of TrustZone is
doubtful - see e.g. the Motorola TrustZone implementation issues, and may
therefore not be sufficient for some applications.
We therefore still think that making use of (potentially changeable) secure
elements is useful.
Concerning the storage of Bitcoin private keys on the secure element and
signing messages on behalf of the Android app, there is still a major
advantage: when the private key is stored in the app and is stolen, then the
user has no control whatsoever. If the key is on the secure element and a
malicious app passes the SE data tgo sign, then we still have the option of
(e.g. based on heuristics) double-checking with the user before signing that
specific item of data passed from Android user land. To summarize, I don't
fully agree that the Javacard applet would just sign everything passed to it.
Original comment by rene.may...@googlemail.com
on 30 Sep 2013 at 10:26
My understanding was that it used a SE (javacard) but I could well be wrong
about that. Regardless, it won't be possible for end user apps to run custom
code in the protected domain. Upgrading it would require changes to Android.
Someone from YubiCo has been developing a JavaCard applet that does signing and
yes, relying on heuristics is his plan too. His applet runs in an external
device that communicates using NFC. I imagine it would be quite easy to defeat
such heuristics, but if I'm wrong I'll be happy about it. You could talk to him
(dain@yubico.com).
BTW in the Motorola case the problem wasn't with TrustZone which seems to work
fine. The problem is that the code that was protected by TrustZone had some
trivial exploits in it. Writing secure code in C is hard and they didn't even
bother getting it audited by a specialist, it seems.
Original comment by hearn@google.com
on 30 Sep 2013 at 10:29
I fully agree about the TrustZone case. My point was that implementations based
on TrustZone seem to be less secure (at least at the moment) than Javacard
based implementations (again, at least so far).
We are actually working on enabling an open eco system of secure code for
execution on Javacards that can ship with normal Android apps. Our current AOSP
fork includes code to - programmatically from within Android - manage applets
on domains of any attached Javacard. We are well aware that this depends on a
workflow for signing the applets that has not yet been defined, but we are e.g.
working together with a bank that might go for MicroSD based or UICC secure
elements for the time being (until access to the embedded secure element
becomes possible). The possibility we see is that device manufacturers (or
MNOs) could create separate security domains that are open to management from
third party apps.
(None of the above deals with TrustZone protected third-party code, we are only
dealing with third-party code on Javacards so far.)
Original comment by rene.may...@googlemail.com
on 30 Sep 2013 at 10:49
Right. It's much harder to screw up in Java than in C.
If you have a real game plan to make secure, compartmentalised code on Android
phones with reasonable heuristics, I'll be cheering for you all the way. I
closed this bug because right now it'd be a large effort that would involve not
only changes to bitcoinj but Android and possibly phone hardware as well, so
it's out of scope for a bug.
I'd suggest you start by picking some heuristics, implementing them in a
standard Java program and then asking users to attack it. You could incentivise
them by putting some money into a wallet and then exposing the basic operations
you'd expose from the JavaCard applet over the internet instead. Whoever
empties the wallet the fastest wins.
Original comment by hearn@google.com
on 30 Sep 2013 at 10:54
When would you actually ask the Javacard to sign something for the Android app?
Only when spending money or also for "housekeeping stuff"? Because then we
could always ask the user to accept the transaction (the same way we would ask
a user to accept using a VPN private key for establishing a connection, e.g.).
(Sorry if this is a stupid question, but I have not personally looked at the
asymmetric crypto in Bitcoin clients so far.)
Original comment by rene.may...@googlemail.com
on 30 Sep 2013 at 11:06
At the moment only when the user initiates an action. In future maybe more
often in the background. We already did a background transaction for the key
rotation.
Original comment by hearn@google.com
on 30 Sep 2013 at 11:15
That might be easy to handle as an exception that doesn't require user
interaction, though (assuming that key rotation can be clearly detected on the
signing side).
Original comment by rene.may...@googlemail.com
on 30 Sep 2013 at 11:25
Original issue reported on code.google.com by
mytrial4@gmail.com
on 28 Sep 2013 at 4:22