Wallet開発のセキュリティ

#はじめに
どうもぼー太郎です。

メリークリスマス？！
どうでもいいんですけど今日は私の誕生日です。
ちょうどTwitterで見た時にカレンダーが開いていたので、
せっかく[IchiGo](https://ichigo-word.fun)と言うSNS内に
Symbol-TESTNET用ウォレットを実装した時のセキュリティについて考えてみます。


仮想通貨の案件来たけどセキュリティってどうするの？
イブなのでふわっとお伝えいたします。

あっ僕への誕生日プレゼントはXEMでお願いしますｗ
NDI3QVDVARK5WLN24PA6TII2H44H26EG763WQQZ4




##ウォレット開発の注意点
まずウォレット開発する機会ってあまりないですよね。
ウォレットを素人が作れる時代になったのがまだ信じられない感じがします。
そんなドリームを叶えてくれたのがSymbol from NEMの技術です。
新しい分野ですし、正解がないし大手の○○Payでも残念な結果が多くて、
○○Pay創世記には散っていったアプリがありましたね。
Symbol from NEM によって開発の敷居が下がった分、
改め注意して開発しないといけません。

重要なのは不正に出金、送金させない仕組みにする事です。
不正が起きたのは言わゆるブロックチェーンじゃなくて既存のシステムに頼った仕組みが原因の一つです。
Symbolをはじめとするブロックチェーン仮想通貨では公開鍵と秘密鍵で暗号化することが前提になっているで、セキュリティを確保しやすいです。
しかしそれを扱うシステムに隙があっては元も子ありません。




##要点は一つ
秘密鍵を流出させない仕組みを取る事です。
この一点に注力して開発すればセキュリティは確保されます。
とにかく秘密鍵が肝になってきます。

##通信経路に乗せない
基本的なことですが、通信経路はHTTPSで暗号化されている場合を除いては、
第三者に通信情報を取られています。
Symbolをはじめとするブロックチェーンでは暗号化してから送信するのでTransactionはHTTPで送信することに問題はありません。
しかしこれから開発するシステムが秘密鍵を送信してしまっては意味がありません。
Symbolのライブラリを利用すればサーバー、クライアント共に簡単に秘密鍵を作成することができます。
サーバーで作った秘密鍵はサーバーで使い、クライアントで作った秘密鍵はクライアント側で使うように（通信経路に乗せない）徹底します。

送金の度にどちらかに秘密鍵を送るような仕組みはさけてください。

IchiGoWalletではクライアント側ブラウザーのローカルストレージに秘密鍵を暗号化して保存しています。
盗まれても複合しないと使用できません。

##ローカルストレージでいいのか？
クライアント側の秘密鍵の保持方法はローカルストレージ＋暗号化でいいのか？

これは正直まだ誰もわかりません。私がchromeの開発者ならより堅固な保存領域を用意するかもしれません。
OSレベルで権限を付けたブラウザークライアント保存領域がまだ世界にないので、実装をまたれます。
これからこういった秘密鍵の保持するサービスが増えればそういったブラウザーが開発されるかもしれませんし、
私が開発するかもしれませんｗ
しかし、現状ローカルストレージに暗号化して保存しておけば、まぁよっぽどな事がないとどうにもできないと思います。
IchiGoWalletの場合ウォレットと言う性質上、持ち歩く=プライベートな端末=ある程度そもそもロックがかかってある？

ローカルストレージストレージなのであくまでIchiGoのアカウントとは関係なしに端末ごとに秘密鍵を入れないと利用できません。

##盗まれるパターンを常に考える。
クリスマスイブですし現実逃避したいですが、ここは正々堂々こうやったら盗まれるという事をあらかじめしっかり考えておく必要があります。

##IchiGoWalletで盗む方法
うぉい！クリスマスだぞ！なんて話だ！ｗ

まずローカルストレージに秘密鍵はあります。
これは端末ごとにブラウザーがもつ保存領域です。
ターゲットの端末を盗む必要があります。
グーグルアカウントのアドレスとパスワードだけを盗んでもダメです。
『端末本体』が必要になります。

では落とした端末を拾ったパターンです。
このパターンでは端末にロックがかかっているかいないか？が最初の関門になります。

ロックがかかってない場合はブラウザーを立ち上げてIchiGoにアクセスします。
IchiGoにログイン出来るのか？
自動ログインがあるので数日以内にログインしていればログイン可能です。
期限が過ぎていれば、ログアウトでパスワードが必要になります。
しかし多くの方がchromeにパスワードを保存しているとお思うので
ログアウトしていても容易にログインに成功するでしょう。


ここで？？ってなっているエンジニアの方々はもう少しがまんしてください。（いや我慢しなくていいですｗ）
逆にふむふむ。となったかたは危ないかもしれません。



そして自動ログインが有効でIchiGoにログインされました。
やばいですね。。。。
クリスマスに泥棒さんがウォレットを起動して自分のアドレスに送信しようとします。
おぅここで最後の砦、別系統のwalletパスワードです。
これがわかるかな？これが分かると盗まれます。

泥棒さんはウォレットのパスワードが分からずに悩んでいると
そうこうしているうちに落とした持ち主がGPSを頼りにやってきました。。。。。
あっこれあなたのですか？いま届けるところだったんですよ。
ありがとうございますと泥棒さんにお礼を申し上げ無事に戻ってきたスマホをみてほっとします。
残高も変わってないし一安心です。

最後の砦ウォレットパスワードで助かりました。


しかし数日後不審な送金が発生してしまいました。

なぜでしょうか？

泥棒さんはどうやって盗んだのでしょうか？

考えられるパターンはありますか？

##IchiGoWalletの脆弱性
まず？？ってなるポイントの解説です。
ここで大事な話ですがローカルストレージはブラウザーの起動と関係ありません。
端末に保存されています。誰でもアクセスできます（OSによって軽い設定がいる）。
ローカルストレージのデータを取るのにIchiGoへのログインは不要です。

泥棒さんはスマホを拾ったときにストレージにアクセスして秘密鍵を盗んだのかもしれません。
もしくはPCに接続してデベロッパーコンソールからローカルストレージデータを盗んだ可能性もあります。
しかし秘密鍵は暗号化して保存してあります。
泥棒さんは暗号を解読したのでしょうか？
ゼロではないですが、５１％攻撃の方が可能性は高そうな話ですｗ
（それができればあらゆるパスワードをゲットしてしまう能力）

##なぜ盗まれたのか？
泥棒さんが盗んだのはスマホのアドレス帳にある個人情報です。

IchiGoのパスワードが推測されたのです。
泥棒さんは暗号化された秘密鍵の暗号を解読するより簡単でした。
というより泥棒さんは秘密鍵の事もローカルストレージのことも知りませんｗｗ

ただパスワードが名前＋生年月日になっていた。
そしてウォレットのパスワードが生年月日。。。。
うぇい！

クレジットカードと一緒だよ！暗証番号！ばれたら終わり！


##まとめ


１.通信経路に乗せない。
２.暗号化してローカルストレージなどに保存。
３.システムとは別系統の送信パスワードロックを実装する。
４.パスワードは推測されないものにする。（してもらうよう促す）
５.スマホは必ずロックしてもらう。

以上を気を付ければ現状ベストだと思います。



大前提にウォレットが入ってるスマホはロックしておくｗ
↑これでだいたい防げるｗ
そもそも推測されては端末もクソもへったくれもございませんｗ

クリスマスにスマホおっことしてクリスマスイブラップを歌わないように祈ります(*‘∀‘)
メリークリスマス♪(*‘∀‘)