暗号通貨に関する事など

暗号通貨に関する覚書など。メモや日記。

※技術的なことに関して、間違っていたらコメントから指摘していただけると泣いて喜びます

仮想通貨 中古のウォレットは危険ですよという話

 ツイッターを見ていて気になったことがあったので書きます。


 中古のハードウェアウォレットのことです。


 結論を先に言います。
 中古のハードウェアウォレットは絶対買ってはいけません。


 これね。別に転売がどうとかは個人的にはどうでも良いのですが、わざわざ高いお金払って危険なウォレットを買う必要はないです。


 理由は文字にしてしまえば簡単なのですが、より危機感を持って貰うために「どうやって攻撃するか」を書いていきたいと思います。(悪用しないでね)



要するに攻撃側は秘密鍵を盗めば良い

 ハードウェアウォレットは「秘密鍵」と呼ばれるものを管理する道具です。この秘密鍵はブロックチェーン上にある自分の資産を使うための鍵であり、秘密鍵を知っていればその資産が誰の資産であれ、使用することが出来ます。
(ちょうど、貴方のツイッターのパスワードを知っていれば貴方でなくても貴方のアカウントでツイート出来るのと同じです)

 結局のところ攻撃側は「いかに秘密鍵を盗むか」を考えればよいのです。
 (秘密鍵を知らなくても攻撃できます)



ハードウェアウォレットの転売を利用して秘密鍵を盗む その1

 では、ハードウェアウォレットの転売を利用して相手の秘密鍵を盗むにはどうすればよいか。


 とても簡単です。「秘密鍵を見てから売れば良い」だけです。手順は下記の通り。

  1. ハードウェアウォレットを購入してそのハードウォレットの秘密鍵をメモする
  2. 転売する
  3. 購入者がハードウェアウォレットの初期化を行わなければ攻撃成功。購入者と販売者は同じ秘密鍵を持っていることになる。

 とっても簡単ですね。明日からでも出来そうです。(やめてください)


 転売されているハードウェアウォレットを買う層は必然的にセキュリティに対する考えが甘い人が多く、初期化の重要性を知らずに初期化せずに利用するケースも多々あると思います。転売することでセキュリティに対する考えが甘い人を炙り出すことも出来るので攻撃の成功率も上げられそうです。


 では、初期化すれば良いのか。と思うでしょう。


 残念ながら、それは違います。



ハードウェアウォレットの転売を利用して秘密鍵を盗む その2

 攻撃その1を見て、初期化すればいいんでしょ?と思いましたか?それは甘いです。


 ハードウェアウォレットが攻撃者によって改造されていれば、実は初期化されていない、初期化はされるが攻撃者が予測できる形に初期化されているかもしれません。

 こうなると、気づくことが困難なので、安心して大金を預けた瞬間、資産をごっそり盗まれてしまいます。



そんなことする人が本当にいるのか?

 その1、その2、いずれも、販売側が攻撃者であることは間違いなく、足がついてしまう。それなのに、本当にそんなことする人がいるのか?

 残念ながら、いるでしょう


 攻撃側はリスクが少ないですからね。大金が手に入るなら迷わずやる人は大勢いると考えるべきです。セキュリティにおいては、性悪説でいきましょう。
(私にしてみれば実際にいるとか、そういうレベルの話ではない)


 また、ここに書いてあるのはあくまで一例で、改造されている場合、何をされているかわかりません。攻撃方法は多彩です。例えば、送金先を差し替える攻撃なら秘密鍵は必要ないのでもっと簡単な改造で攻撃できそうです。



フィジカルコインも危険だよ

 フィジカルコインってありますよね。コインっぽい形したものに秘密鍵を刻んで封してる、あれです。中には掘ってから一度も使われてないヴァージンコインをフィジカルコインにして売るっていうのもあったりするようです。(使われてないコインが欲しいとかどんだけ変態なんdry)

 (上記図:例のアレ)


 で、これも言わずもがな危険ですよね。攻撃方法は「その1」と同じです。

 昔からビットコインに目をつけていた所謂「古参」と呼ばれる方々も記念に買っていたりするので、ついつい安全なものかと思ってしまいがちですが、あれはとても危険なものです。
(古参の人はそれを理解した上で、それでも記念にと考えて買っています。)



泣き寝入りするしか無いという悲しい現実

 盗まれた場合、どうなるのか。


 残念ながら、泣き寝入りするしかありません。


 なぜか。ビットコインをはじめ、仮想通貨には基本的に発行主体というものがなく、泣きつく先が無いからです。貴方がハードウェアウォレットから資産を盗まれた時、皆貴方のことを可哀想に思うでしょう。しかし、残念ながらどうすることも出来ないのです。


 日本円であれば、不正送金先を見つけ、強制的に取り戻すことが出来るでしょう。しかし、仮想通貨の場合、不正に送金された先が分かったところで誰にも手出しが出来ないのです。残念なことに。この辺りは取引所の利用者保護の限界にも関わってくる話でしょう。



資産を守るためなので、油断するな

 上に書いたことは仮想通貨を守るというよりは、パスワードを複雑にする、パスワードは使いまわさないなどの、一般的なネットセキュリティーの延長にあるものです。特別仮想通貨に限ったことでもありません。


 せっかくトレードでいい成績を収めても、盗まれればおしまいです。


 だから油断するな。

Segwitに関して調べた記録6


前回の続き



Segwitで採用される新しいアドレスフォーマット(はじめに)

 その送金先がSegwitアドレスであることを示す為のアドレスフォーマットについてここでは書く。


 Segwitのアドレスフォーマットは元々BIP-142に定められていたのだが、後にそれを上書きするものとして、BIP-173が提案された。


 BIPは提案なので、実際にBitcoinがSegwitを導入できていない今、BIP-142とBIP-173のどちらが採用されることになるかは、正直わからないのだが、先にSegwitを導入しているLitecoinを見るに、BIP-173が採用される確率が高いと思うので、BIP-173について書く。


 LitecoinではBIP-173の導入を決定しているようで、次の大きなバージョンアップの時に導入するとかしないとか(現時点で導入はされていない)


https://github.com/litecoin-project/litecoin/issues/312
(何かその辺りの会話してるね・・・)



BIP-173


 GithubにアップされたBIP-173はこちら


 BIP-173はSegwitのアドレスフォーマットを定めたもので、大まかな流れは以下のとおりである

  1. witnessProgramにhuman-readable partと呼ばれるデータを付ける
  2. 1のデータに間違い検証用のデータである"チェックサム"を付ける
  3. 2のデータ部分をBIP-173で定められた方法で32文字を使用したデータにエンコードする

 では、まず最初にBech32から説明していく。



Bech32

 BIP-173では、Base58を用いたレガシーなアドレスエンコードに対して、Bech32と呼ばれるエンコードを提案している。


 このBech32は、「human-readable part(人が読む部分)」と「data part(データ部分)」とに分かれており、それらを区切るものとして「separator(セパレーター)」と呼ばれる特定の文字を使用する。



 各パートの意味するところは上記図を見て欲しい。セパレーターは「1」で固定されており、もし、human-readable partに1が複数回出てくる場合は、その一番後ろのものをセパレーターと認識する。(Bech32エンコード後のdata partには1は使われない)


 data part(以下 "データ部分")はバイナリデータをBech32で定められる32文字のデータでエンコードされる。


 ここで注意しておきたいのが、Bech32に使われる文字表は通常のBase32と文字の並びが違うということだ。実際にはBIP-173にかかれている表を見て欲しいが、通常のBase32が「a,b,c...」と始まるところを「q,p,z...」となっている。


BIP-173より引用

bips/bip-0173.mediawiki at master · bitcoin/bips · GitHub

 都合上表にしているだけで、単に連なった32文字だと思えば良い。(q,p,z...x,8,g,f...)


 次に、チェックサムについて説明をする。



チェックサム

 チェックサムはデータ部分に含まれる。


 チェックサムは、下記Pythonで書かれたコードの「bech32_verify_checksum」メソッドがtrueを返すことでその検証が成功したものとみなす。

BIP-173より引用

bips/bip-0173.mediawiki at master · bitcoin/bips · GitHub

 生成に関しては、下記Pythonのコードに従って生成を行う。

BIP-173より引用

bips/bip-0173.mediawiki at master · bitcoin/bips · GitHub

 この辺りのプロセスは実際にコードを読んでその手順を追って欲しい。


 BIP-173にもその説明が簡単にされているが、この計算は「BCH符号」と呼ばれるデータの符号化の計算として最も研究がされているものの一つを利用した計算のようだ。



Sgwitのアドレスフォーマット

 以上を踏まえて、Segwitのアドレスフォーマットに関わる規則は下記のとおりとなっている。


■human-readable part
 各通貨に依る(Bitcoinであればbc,Litecoinであればltcなど)


■data part
 1文字目はwitnessVersionになる。
(version0だと上記で引用した表より"q"となる)


 残りのwitnessProgramとチェックサムの部分は0と1のバイナリデータとして見て5bit毎に区切り(端数はパディングする)、それらを表に記された32個の文字に当てはめていく。
(2の5乗は32なので、5bit毎に区切れば32個の文字列に当てはめることが出来る)


 BIP-173のサンプルを見ると分かるが、例えば"Bitcoin(mainnet)"の"version0"の"WitnessProgram"のアドレスは、必ず「bc1q」から始まる。この時、"bc"がhuman-readable partで"1"がseparator、"q"がversion0の"0"を示している。この後に、witnessProgramとチェックサムを32文字でエンコードした文字が続く。



このパートの最後に

 以上がBIP-173で定められた新しいアドレスフォーマットの詳細になる。正直、実際に自分で実装してみないと分からないと思う。サンプルもあるので実際に自分で生成したほうが良いと思う。また、実装しているうちに新たにわからないところが出てくると思う。(私はそもそもBCH符号化の操作に関してその根拠がよく分かっていない)


 なんだか良く分からないチェックサムの計算だが、SHA-256doubleHashしたデータの頭4byteを抜き出すよりは素早く、より厳密に間違い検証が出来るようだ。


 また、定義が曖昧になってしまったがBech32は表で指定された32文字を用いたデータのエンコードそのものを指すのではなく、チェックサムの計算方法やアドレスフォーマットなど、BIP-173で定められた全ての操作をまとめてBech32と呼ぶようなので、注意して欲しい。



最後に(全体的に)

 今回を含む全6回分の記事に書いてあることがSegwitについて私が調べたことだ。なので今回でおわり。


 正直後半は息切れしながら書いたので説明が雑になってしまったがまぁ仕方ない。

仮想通貨NEM 触って楽しいAPIのお話

はじめに

 仮想通貨NEMにはAPIと呼ばれる機能がついており、それによって誰でも簡単にブロックチェーンの力を得ることが出来る。今回はそのことについて書く。



APIとは

 そもそもAPIとは何なのか。


 APIとは、「アプリケーション・プログラミング・インターフェース(Application Programming Interface)」の略で、本来の意味としてはソフトウェア同士がデータをやり取りするための窓口とそれを使うための取説、仕様全般を指すのだが、取引所やツイッターなどで目にするAPIは意味がすこし狭くなっていて、「インターネットを通じてサーバーとデータのやり取りをする為の窓口」だと思えば良い。


 APIを利用することで得られる恩恵は何か。例えば取引所であれば、通常ブラウザを使って取引所にログイン後、手動で売り買いをしなくてはいけないところ、APIを利用することで、ブラウザを使わなくても取引所のサーバーと直接データのやり取りが可能になり、自作のソフトを作って取引することや、さらには自動で売買を行うプログラムを作ってプログラムに売買を任せることが出来るようになる。



NEMのAPI

 では、NEMのAPIでは何が出来るのか。基本的にNEMに出来ることはAPIで何でも出来る。聞くより使ってみたほうが早いと思うので実際に使ってみよう。


【下のいずれかのURLをクリック!(別窓開きます)】
http://45.76.107.205:7890/heartbeat
http://153.122.13.168:7890/heartbeat
http://160.16.181.49:7890/heartbeat


 クリックすると、下記のようななんだか良く分からない記号と英数字の羅列が出てきたのではないだろうか。(出てこなかったら通信失敗。別のURLを試そう)

{"code":1,"type":2,"message":"ok"}

 で、このURLと謎の記号と英数字の羅列は何なんだという話だが、まず、URLについて、一番上のURLを使って解説しよう。



URL構造

 これはNEMではなくてウェブの話になるが、URLをクリックするということは、下記のリクエストをインターネットに送ったということを意味する。

 これを役所の手続きで例えるとこんな感じになる。

 今回のリクエストでは45.76.107.205の住所にあるノードの7890番の窓口にハードビートリクエストを送ったことになる。



ハートビートリクエスト

 では送った"ハートビートリクエスト"とは何か?ハートビートを直訳すると「心臓の鼓動」で、このハートビートリクエストではリクエスト先のノードが生きているか、死んでいるか(サーバーがダウンしていないか)確認するためにある。


 リクエストを送ってノードから返ってきた答えは次のように読むことが出来る。

 code:1が何を示すのか、などは、APIリファレンス(APIの取説)を読むとわかる。
 (APIリファレンス(英文):http://bob.nem.ninja/docs/


 何となくイメージが掴めただろうか?やっていることはAPIで定められたフォーマットでリクエストを送って、その返信を受け取る作業だ。まさに役所の手続きのようなもの。


 手続きの一覧(利用可なリクエストやリクエストを送る時のフォーマットなど)はAPIリファレンスに載っている。



アドレスの中身を確認するリクエスト

 では続いて、アドレスの中身を確認するリクエストを送ってみよう。
 今回は「NB7J657L7TBNKXOGXQJVP5VEKQODTDZORPW3ZF3Y」のアドレスの中身を覗いてみる。NEMのブロックチェーンは公開台帳なので、誰でもその中身を覗くことが出来る。


【下のいずれかのURLをクリック!(別窓開きます)】
http://45.76.107.205:7890/account/get?address=NB7J657L7TBNKXOGXQJVP5VEKQODTDZORPW3ZF3Y


http://153.122.13.168:7890/account/get?address=NB7J657L7TBNKXOGXQJVP5VEKQODTDZORPW3ZF3Y


http://160.16.181.49:7890/account/get?address=NB7J657L7TBNKXOGXQJVP5VEKQODTDZORPW3ZF3Y


 正常に通信ができていてば、以下のように画面に表示されているはず。

{"meta":{"cosignatories":[],"cosignatoryOf":[],"status":"LOCKED","remoteStatus":"REMOTE"},"account":{"address":"NB7J657L7TBNKXOGXQJVP5VEKQODTDZORPW3ZF3Y","harvestedBlocks":0,"balance":0,"importance":0.0,"vestedBalance":0,"publicKey":"5b82a2d4eb135875465c977adad22260e5c7bd62051709a3d1dedc1809a8057c","label":null,"multisigInfo":{}}}

 さっきのハートビートリクエストよりも複雑だが、基本的には読み方は同じだ。各ステータスの結果の意味はリファレンスを見ながら読んでいくことになる。


 各ステータスが示す細かい話は置いていおて、とりあえずこのアカウントにどれだけのxemが入っているかを確認するには、次の場所を確認すれば良い。

{"meta":{"cosignatories":[],"cosignatoryOf":[],"status":"LOCKED","remoteStatus":"REMOTE"},"account":{"address":"NB7J657L7TBNKXOGXQJVP5VEKQODTDZORPW3ZF3Y","harvestedBlocks":0,"balance":0,"importance":0.0,"vestedBalance":0,"publicKey":"5b82a2d4eb135875465c977adad22260e5c7bd62051709a3d1dedc1809a8057c","label":null,"multisigInfo":{}}}

 balanceステータスがこのアドレスに含まれるxemを示す。それによると、NB7J657L7TBNKXOGXQJVP5VEKQODTDZORPW3ZF3Yに入っているxemは0であることがわかる。


 ちなみに、他のアドレス(例えば自分が管理しているアドレス)を覗いてみたい場合は…

http://45.76.107.205:7890/account/get?address=NB7J657L7TBNKXOGXQJVP5VEKQODTDZORPW3ZF3Y

 上記の着色部分がアドレスを指定する部分になっているので、そこを自分が管理するアドレスに書き換えれば良い。



 駆け足になったが、APIで出来ることが理解できただろうか?この他にも、トランザクションの生成(送金)なども出来るが、処理が複雑なのでここでは紹介しない。気になればAPIリファレンスを読みながら試してみると良いだろう。



API機能はNEMだけにしか無いのか

 便利なAPI機能だが、ではビットコインやライトコイン、モナコインなどの標準クライアントには付いていないのか。


 実は、ビットコインなどにもAPI機能は付いている。そのため、やろうと思えば上記で示したようなことをビットコインで再現することも可能だ。だが、ビットコインではセキュリティの観点から基本的に得体の知れない外部からのリクエストにAPIが応えるべきではないとしている。


 そのため、通常ビットコインなどを利用したサービスは下のような体制をとることになる。

 
 だが、外部からのAPIアクセスを認めたNEMでは、下のような体制を取ることが出来る。

 これが何を意味するのかというと、クライアント側だけを作ってブロックチェーンを利用したアプリを作ることが出来ることを意味する。しかも、自分でいくつもノードを建てなくても単一障害点のないアプリを作ることが出来る。
(その代表的な例がNanoWalletになる)



APIを利用する上で参考となる外部リンク

■NEMの説明書
 APIリファレンスの和訳をしてくれている。


■Qiita&mijinフォーラム(takanobuさんの記事)
 基本的なとろこから細かく解説してくれている。さらに、mijinフォーラムから実際にNEMのAPIを使用して作られた"NEMBook"を使ってみるとAPIのパワーを感じることが出来る。


■Qiita(him0さんの記事)
 トランザクション生成について説明してくれている。


■kataribe(tadajamさんの記事)
 この記事以外にもkataribe内で色々な記事がある。



最後に

 簡単だが以上をNEMのAPIについての説明とする。「ボット」と呼ばれるような自動売買プログラムを簡単にでも作ったことがある人であればそれほど難しい話ではないと思う。触ってみても、アドレスに紐づくUTXOがどうだとかブロックチェーンの仕組みがどうだなどと考える必要もない。(NEMはそもそもUTXOではないけど…)非常に便利だと感じる。


 しかしここで一点注意をしておきたいことがある。仕様変更についてだ。NEMではカタパルトによってその構造自体が変わる予定があるので、もしかしたら大きなAPIの仕様変更があるかも知れない。今からなにか作ろうと思っている方は注意が必要だ。


チャオ☆