novitski / bitcoinj

Automatically exported from code.google.com/p/bitcoinj
Apache License 2.0
0 stars 0 forks source link

ECKey generation and storing in secure elements #462

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Imported from 
https://code.google.com/p/bitcoin-wallet/issues/detail?can=2&start=0&num=100&q=&
colspec=ID%20Type%20Status%20Priority%20Milestone%20Owner%20Summary&groupby=&sor
t=&id=228

Original issue reported on code.google.com by mytrial4@gmail.com on 28 Sep 2013 at 4:22

GoogleCodeExporter commented 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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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

GoogleCodeExporter commented 9 years ago
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