Slide 1

Slide 1 text

いかにして ビットコインを扱うか DroidKaigi 2019 @yuikijp 1

Slide 2

Slide 2 text

ゆいき / Taiki Uchida > 筑波大学 情報科学類 2年 > Previously at: @mikan_link @yenom_wallet > Android歴: 5年 > 最近: kotnes, Rust, Flutter > Twitter: @yuikijp 自己紹介 2

Slide 3

Slide 3 text

アジェンダ 1. ビットコインとは 2. ビットコインをAndroidで扱う上で a. いかにして通信するか b. いかにして秘密鍵を保持するか 3. Copayウォレット バックドア事件 3

Slide 4

Slide 4 text

モチベーション ◉ モバイル x Bitcoinの話が少ない ○ DroidKaigi 初? ◉ ビットコインが生まれて早10年 暗号通貨周りに関しての理解を促進したい 4

Slide 5

Slide 5 text

ビットコインとは? 1 5

Slide 6

Slide 6 text

ビットコイン 明示的な管理者無しに P2Pネットワークで 送金できるプログラマブルなお金 6 1. ビットコインとは?

Slide 7

Slide 7 text

ビットコインを支える技術 ◉ ブロックチェーン ◉ Proof of Work (PoW) ◉ 公開鍵暗号 ◉ 楕円曲線デジタル署名アルゴリズム (ECDSA) ◉ ハッシュ関数 (SHA-256) ◉ マークルツリー ◉ Simple Payment Verification (SPV) ◉ etc... 7 1. ビットコインとは?

Slide 8

Slide 8 text

詳しく知りたい方は Mastering Bitcoin Web (無料) https://bitcoinbook.info/ 本 https://www.amazon.co.jp/dp/4757103670 8 1. ビットコインとは?

Slide 9

Slide 9 text

暗号通貨系のアプリ 9 1. ビットコインとは?

Slide 10

Slide 10 text

暗号通貨系のアプリ ◉ 取引所系…法定通貨と暗号通貨などを交換する取引所が出 しているアプリ ◉ ウォレット…暗号通貨を保持、送受金する機能を持つ ◉ DAppsブラウザ…ブロックチェーン等で動くアプリを使う ためのウォレット内蔵型専用ブラウザ ◉ etc... 10 1. ビットコインとは?

Slide 11

Slide 11 text

共通の問題 11 1. ビットコインとは?

Slide 12

Slide 12 text

共通の問題 ◉ いかにして通信するか ◉ いかにして秘密鍵を保持するか 12 1. ビットコインとは?

Slide 13

Slide 13 text

いかにして通信するか 13 2

Slide 14

Slide 14 text

そもそも何を通信するのか 14 2. いかにして通信するか

Slide 15

Slide 15 text

通信内容 トランザクション (+α) ◉ 送金/コントラクトの実行→トランザクションの作成、送信 ◉ 着金→トランザクションの受け取り ◉ 残高確認→トランザクション履歴の取得 ◉ etc... 15 2. いかにして通信するか

Slide 16

Slide 16 text

主なウォレットの種類 ◉ フルノード型 ◉ SPV クライアント型 ◉ API クライアント型 16 2. いかにして通信するか

Slide 17

Slide 17 text

フルノード すべてのブロックとトランザクションを取得し て検証するノード ◉ ブロックチェーンの全ての情報を保持してい る ◉ 現時点で200GB程度の空き容量が必要 主な実装: Bitcoin Core - https://github.com/bitcoin/bitcoin 17 2. いかにして通信するか

Slide 18

Slide 18 text

SPVクライアント モバイル環境等でも利用可能なようにした軽量 クライアント ◉ 自分に関係するトランザクションを一部検証 する ◉ ブロックヘッダを保持する(40MB程度) 主な実装: bitcoinj - https://github.com/bitcoinj/bitcoinj 18 2. いかにして通信するか

Slide 19

Slide 19 text

API クライアント フルノードをREST API等を経由して利用する 主な実装: (クライアント) copay - https://github.com/bitpay/copay (サーバ) bitcore - https://github.com/bitpay/bitcore 19 2. いかにして通信するか

Slide 20

Slide 20 text

通信方法の比較 方法 サイズ 通信量 検証 フルノード ☓ (200GB) ☓ ◎ SPV クライアント ○(40MB) △ ○ API クライアント ◎ ◎ ☓ 20 2. いかにして通信するか

Slide 21

Slide 21 text

どれをつかえばいい? アプリで使うなら容量や通信量の関係上、SPVかAPIクライアント 自社のサーバだけ依存させずにビットコインネットワークのメ リット(分散)を活かすならSPVクライアント 自社ですべてハンドリングしたい場合はAPIクライアント SPVとAPIのハイブリットという手もある 21 2. いかにして通信するか

Slide 22

Slide 22 text

ところで… 22 2. いかにして通信するか

Slide 23

Slide 23 text

bitcoinjで送金 (SPV) 23 val kit = WalletAppKit(TestNet3Params(), File("."), "") // セットアップを開始する kit.startAsync() // セットアップを待つ kit.awaitRunning() // 残高 val balance = kit.wallet().getBalance() // アドレス val address = kit.wallet().currentReceiveAddress() // 送金 kit.wallet().sendCoins(kit.peerGroup(), "address", Coin.COIN) bitcoinj - https://github.com/bitcoinj/bitcoinj チュートリアル作りました ! - https://hackmd.io/s/HyTPzbeLm 2. いかにして通信するか

Slide 24

Slide 24 text

SPVの改良 信頼性は落ちるが接続数を減らして通信量を減らす BRDは3 https://github.com/breadwallet/breadwallet-core/blob/master/BRPeerMana ger.h#L40 bitcoinjは12 https://github.com/bitcoinj/bitcoinj/blob/2ec193f8479425c3a66bebf5f2d3 493e39e88f7c/core/src/main/java/org/bitcoinj/core/PeerGroup.java#L82 24 val kit = object : WalletAppKit(params, dir, filePrefix) { override fun createPeerGroup(): PeerGroup { return super.createPeerGroup().apply { maxConnections = 8 } } } 2. いかにして通信するか

Slide 25

Slide 25 text

着金通知 ユーザの公開鍵をサーバで保持して、サーバ上 で着金確認を行い、Push通知を送る。 実装例: https://github.com/bitpay/bitcore/tree/master/packages/bitcore-wallet-service 25 2. いかにして通信するか

Slide 26

Slide 26 text

いかにして鍵を保持するか 26 3

Slide 27

Slide 27 text

そもそも鍵が何故必要か 27 3. いかにして鍵を保持するか

Slide 28

Slide 28 text

ビットコイン x 鍵 秘密鍵から不可逆変換でアドレスが生成される そのアドレス宛に送金されたコインは、そのア ドレスと紐づく秘密鍵による署名が無いと利用 できない。 28 3. いかにして鍵を保持するか

Slide 29

Slide 29 text

ビットコイン x 鍵 秘密鍵から不可逆変換でアドレスが生成される そのアドレス宛に送金されたコインは、そのア ドレスと紐づく秘密鍵による署名が無いと利用 できない。 つまり、秘密鍵=コインの所有者 29 3. いかにして鍵を保持するか

Slide 30

Slide 30 text

鍵の管理法 ◉ サーバで持つ ◉ クライアントで持つ 30 3. いかにして鍵を保持するか

Slide 31

Slide 31 text

鍵の管理法の比較 管理場所 観点 特徴 サーバ 事業者 サーバがハックされるリスクを背負 う ユーザ 事業者を信頼して、鍵の管理を任 せる (バックアップをおまかせできる ) クライアント 事業者 サーバで鍵を管理する必要がない ユーザ 自分で鍵を管理する (バックアップが大変) 31 3. いかにして鍵を保持するか

Slide 32

Slide 32 text

今回はクライアントで鍵を持つ話をします 32 3. いかにして鍵を保持するか

Slide 33

Slide 33 text

Android KeyStore 33 3. いかにして鍵を保持するか

Slide 34

Slide 34 text

Android KeyStore ◉ 安全な領域で鍵を生成、保持できる 34 3. いかにして鍵を保持するか

Slide 35

Slide 35 text

Android KeyStore ◉ 安全な領域で鍵を生成、保持できる ◉ しかし、iOSのKeyChainと違ってAndroidのKeyStoreには 任意のデータを入れることができない ◉ アンインストールや指紋の登録解除等で消える 35 3. いかにして鍵を保持するか

Slide 36

Slide 36 text

36 3. いかにして鍵を保持するか

Slide 37

Slide 37 text

鍵の持ち方 37 3. いかにして鍵を保持するか

Slide 38

Slide 38 text

鍵の持ち方 おすすめのものを列挙しているわけではありません。プロダクト毎にセキュリティリスク を考慮して検討してください。あくまで例です。 ◉ 内部領域にそのまま保存する (copay) ◉ 十分な強度のパスフレーズで鍵を生成し、内部ストレージに保存 する(BIP39) ◉ KeyStoreの鍵で暗号化して内部領域に保存する (BRD/Toshi) ◉ ユーザが所持しているデバイス(セキュリティトークン等)で暗号 化する ※ SafetyNet Attestation APIを用いてRoot化検知 https://developer.android.com/training/safetynet/attestation 38 3. いかにして鍵を保持するか

Slide 39

Slide 39 text

将来的な鍵の持ち方 ◉ 端末レベルで暗号通貨鍵の管理、署名が行わ れる未来 ◉ ハードウェアウォレットとスマホの連携 39 3. いかにして鍵を保持するか

Slide 40

Slide 40 text

4 Copayウォレット バックドア事件 (番外編) 40

Slide 41

Slide 41 text

Copayウォレット バックドア事件 41 4. Copayウォレット バックドア事件

Slide 42

Slide 42 text

Copayウォレット バックドア事件 ◉ TypeScript製 マルチプラットフォームウォレット(OSS) 42 4. Copayウォレット バックドア事件

Slide 43

Slide 43 text

Copayウォレット バックドア事件 ◉ TypeScript製 マルチプラットフォームウォレット(OSS) ◉ 秘密鍵を奪取するバックドアが仕組まれた 43 4. Copayウォレット バックドア事件

Slide 44

Slide 44 text

Copayウォレット バックドア事件 ◉ TypeScript製 マルチプラットフォームウォレット(OSS) ◉ 秘密鍵を奪取するバックドアが仕組まれた ◉ 2018年11月末に発覚 44 4. Copayウォレット バックドア事件

Slide 45

Slide 45 text

Copayウォレット バックドア事件 ◉ TypeScript&Cordova製 マルチプラットフォームウォレット(OSS) ◉ 秘密鍵を奪取するバックドアが仕組まれた ◉ 2018年11月末に発覚 ◉ アプリが依存しているライブラリが更に依存し ているライブラリに暗号化された悪意のある コードが混入 45 4. Copayウォレット バックドア事件

Slide 46

Slide 46 text

Copayウォレット バックドア事件 copay event-sream flatmap-stream 依存 依存 46 4. Copayウォレット バックドア事件

Slide 47

Slide 47 text

Copayウォレット バックドア事件 copay event-sream flatmap-stream 依存 依存 47 ◉ 広く使われてい るBTC/BCHウォ レット ◉ 200万DL/週 ◉ 攻撃ライブラリ 4. Copayウォレット バックドア事件

Slide 48

Slide 48 text

Copayウォレット バックドア事件 copay event-sream flatmap-stream 依存 依存 ◉ 広く使われてい るBTC/BCHウォ レット ◉ 200万DL/週 ◉ 悪意のあるコー ドを暗号化して 圧縮済みファイ ルに混入 48 ◉ 攻撃ライブラリ ◉ 悪意のある人がメ ンテナ権限を受け 取り flatmap-stream への依存を追加 ◉ event-stream に以前から依存 4. Copayウォレット バックドア事件

Slide 49

Slide 49 text

ポイント 49 4. Copayウォレット バックドア事件

Slide 50

Slide 50 text

ポイント 50 多くの人に関係があると言える 4. Copayウォレット バックドア事件

Slide 51

Slide 51 text

ポイント 51 多くの人に関係があると言える ◉ OSSとは切っても切り離せない開発環境 4. Copayウォレット バックドア事件

Slide 52

Slide 52 text

ポイント 52 多くの人に関係があると言える ◉ OSSとは切っても切り離せない開発環境 ◉ 趣味等でOSSを開発している人も多い 4. Copayウォレット バックドア事件

Slide 53

Slide 53 text

ポイント 53 多くの人に関係があると言える ◉ OSSとは切っても切り離せない開発環境 ◉ 趣味等でOSSを開発している人も多い > I created it for fun https://gist.github.com/dominictarr/9fd9c1024c94592bc7268d36b8d83b3a 4. Copayウォレット バックドア事件

Slide 54

Slide 54 text

対策 ◉ アプリ開発者としての対策 ◉ ライブラリ開発者としての対策 54 4. Copayウォレット バックドア事件

Slide 55

Slide 55 text

アプリ開発者 としての対策 55 4. Copayウォレット バックドア事件

Slide 56

Slide 56 text

アプリ開発者としての対策 copayの対策 ◉ メジャーバージョンアップデート時以外では 依存性のアップデートをしないようにした (依存関係のレビューに時間を割きやすいようにした) ◉ 接続可能なURLを制限した。(Androidネイティブでは難しそう) 56 4. Copayウォレット バックドア事件

Slide 57

Slide 57 text

アプリ開発者としての対策 copayの対策 ◉ メジャーバージョンアップデート時以外では 依存性のアップデートをしないようにした (依存関係のレビューに時間を割きやすいようにした) ◉ 接続可能なURLを制限した。(Androidネイティブでは難しそう) その他 ◉ 依存ライブラリが多くなりすぎてないかを確認する ◉ メンテされてないライブラリを使わない ◉ ライブラリを支援する(金銭的/時間的) ◉ (依存先のライブラリをウォッチする) 57 4. Copayウォレット バックドア事件

Slide 58

Slide 58 text

ライブラリ開発者 としての対策 58 4. Copayウォレット バックドア事件

Slide 59

Slide 59 text

ライブラリ開発者としての対策 ◉ 信用できない人にコミット権限やリリース権 限を与えない ◉ アーカイブするという選択肢もある 59 4. Copayウォレット バックドア事件

Slide 60

Slide 60 text

詳しくはこちら ◉ I don't know what to say. · Issue #116 · dominictarr/event-stream https://github.com/dominictarr/event-st ream/issues/116 ◉ Statement on NPM Package Vulnerability in v5.0.2-5.1.0 of Copay Wallets https://blog.bitpay.com/npm-package-vul nerability-copay/ 60 4. Copayウォレット バックドア事件

Slide 61

Slide 61 text

まとめ ◉ ビットコインとは明示的な管理者無しにP2Pネットワークで 送金できるプログラマブルなお金 ◉ 通信量に気をつける。SPVは通信量が多いので接続数を減ら したり、自社APIサーバを使うなどするのも手 ◉ 鍵の保存はケースバイケース。Root検知とKeyStoreの鍵で 暗号化するのがメジャー ◉ 暗号通貨を扱う上でセキュリティに関しては必ず方針を決め ましょう。OSSライブラリの扱いに注意 61

Slide 62

Slide 62 text

> Twitter: @yuikijp ありがとうございました 62 Presentation template by SlidesCarnival