セキュリティモデルの理解

フルブロックチェーンノードとSPVノードの違いと、bitcoinjアプリがどのように攻撃されるかについて学びます。

概要

bitcoinjは、フルブロックチェーンノードとSPVノードの2つの異なるモードをアプリケーションでサポートします。モードの選択は、アプリケーションのリソースの使用量、Bitcoinシステムが他の参加者にどれだけ信頼されるかによって使い分けます。開発者は、この2つのモードの違いを理解し、アプリが信頼できるかどうかを理解する必要があります。

まず、フルノードがどのように動作するかについて確認します。 Bitcoinが解決する問題は、誰が何を所有しているかについて合意を得ることです。
ルノードは全てのノードでUTXOのデータを持っており、存在しなかったり、すでに消費されている出力を使おうとするトランザクションは無視されます。ブロックは誰でもトランザクションを出力することができ、同意を得るためにネットワークにブロードキャストしマイナーによって了承されます。
何らかの理由でブロードキャストしたトランザクションが表示されないノード(例えば、その時点でネットワークにオフラインだったノード)は後からブロックチェーンを読み込む事で追いつくことが出来ます。

トランザクションごとにデータベース更新し格納しチェックする事は非常に極端です。なぜならジェネシスブロックから続くデータベースを最新の状態まだ取得するのに途方もない時間がかかるからです。その為、すべてのPCでフルノードを実行するわけではありません。

次にSPVモードについてです。このモードはウォレットに関連するトランザクションのみが格納されます。他のすべてのトランザクションは破棄されるか、単にダウンロードされることはありません。ブロックチェーンは引き続き使用され、ネットワークにブロードキャストされたトランザクションを受け取りますが、これらのトランザクションはチェックされず、有効であるかは確認できません。SPVモードは、スマートフォンなど容量の少ないデバイスでとても速く軽量に動作しますが、さまざまな方法で無効化されてしまう可能性を持っています。

保留中の取引

複数のトランザクションがブロックに含まれ、ネットワークにブロードキャストされます。マイニングノードはトランザクションを見てチェックし、有効であれば、マイニングしようとしている現在のブロックにトランザクションを含めます。ノードは無効なトランザクションは他のノードに中継しません。

アプリは保留中のトランザクションを受け取り、ウォレットに追加し、イベントリスナーを実行します。SPVモードがトランザクションが有効であると信用する理由は、接続したノードがトランザクションを中継したという根拠に基づいています。不正をするノードが良心的なノードに接続し無効な取引を与え、有効であるかのように振る舞うことが出来ます。

しかし、bitcoinjアプリは接続するノードをランダムが選択するので(DNSシードに基づいています)攻撃者が意図した接続を制御することは難しいのです。トランザクションを送信したピアの数はTransactionConfidenceオブジェクトで公開されています。新しいピアがトランザクションを送信した時に、送信したピアの数を知ることができます。他のほとんどのピアが送信している場合、取引が有効である可能性が非常に高い事ことが確信で​​きます。

この方法に対し、3つの潜在的な攻撃が存在します。

1.インターネット接続全体を乗っ取り、偽物のネットワークに接続します。これはシビル攻撃と呼ばれ、信頼できないインターネット接続(たとえばFree wifi)を使用しているときやTorを使用している時には簡単にできます。 BitcoinjはTorをサポートしていないので、モバイルウォレットを使用する時には特に注意が必要です。

2.2つの無効なトランザクションを同時にブロードキャストし競合状態作りこれを利用します。攻撃者が効果的に攻撃を行うためには、被害者に接続できる必要がありますbitcoinjアプリは受動的な接続を受け付けませんので、これをやりとりするのは難しいです。将来、Bitcoinネットワークは二重払いのアラートを実装する予定ですが、今日は実装されていません。

3.二重払いを含むブロックをマイニングし、Bitcoin決済のサービスを利用し、ブロックをブロードキャストします。これはFinney攻撃と呼ばれています。

Finney攻撃

攻撃者の所有する2つのアドレスAからBにBitcoinを送付し、このトランザクションを含んだブロックをマイニングします。攻撃者はこのブロックを見つけても、すぐにブロードキャストしません。代わりに、未確認トランザクションを受け入れているサービス業者にBitcoin使用し取引を行います。サービス業者から商品を手に入れたら、二重払いを含むこのブロックをブロードキャストし、Bitcoinを攻撃者は取り戻します。

Finney攻撃は、絶妙なタイミングと多大な忍耐に依存しています。ブロックが見つかるまで待つ必要があり、時間がかかることがあります。攻撃者はすぐにサービス業者から何かを買うことができなければなりません。
買った物が手元に来る前に、他のマイナーがこのブロックを見つけてブロードキャストした場合はFinney攻撃は失敗に終わります。

以下の基準を満たしている場合、Finney攻撃を受ける可能性があります。

1.保留中の取引の代償として価値のあるものを不可逆的に販売している(高速入金システムなど)
2.攻撃者が購入する時刻を選択出来る
3.購入するプロセスが速い(数分未満)

Finney攻撃に対する例をいくつか示します。

ビデオゲームダウンロード販売トランザクションの確認なしで販売する自動オンラインストア。24時間365日オープンしているオンラインストアなので、攻撃者はいつ購入を実行するかを選択できます。自動化されているため、購入プロセスは高速です。ダウンロードなので、オンラインライセンスのチェックを取り消すことができない限り、支払いに対して不可逆的です。

・スーパーマーケット。一度店を出ると、支払いは不可逆的です。しかし、攻撃者は購入の正確な時刻をコントロール出来ません。あなたがネットワークでかなりのハッシュパワーを持っていて、1時間毎にブロックを見つけていない限り、またブロックのマイニングが終わるのを待ってスーパーマーケット内に待機することは実現可能ではありません。もしブロックを見つけたとしても、レジの待ち行列によって購入時期は変わります。ブロックが1秒に1回カウントされると、攻撃が失敗する可能性が高くなりますので、購入するまでに時間がかかります。

・対面での取引。多額の不可逆的な取引が行われています。しかし通常、簡易的な方法で対面取引を組織することはできません。事前に多くの組織を必要とします。あなたが他の人と出会い、取引をする時間を提案することはできますが、購買のプロセスには長い時間がかかります。

誰かがあなたのアプリに対してFinney攻撃を実行すると、その取引の"TransactionConfidence"の信頼タイプが "DEAD"に変わり、登録したイベントリスナーが呼び出されます。 「DEAD」取引は、支払いが取り消されたものとして扱われ、残高にはカウントされません。

確認済み取引の信頼性

多くのタイプのアプリケーションは、すぐにサービスを提供するわけではなく、ブロックチェーントランザクションが含まれるの確認するまで待つことできます。トランザクションがチェーンに含まれている場合、TransactionConfidenceタイプはBUILDINGに変更され、トランザクション深度(このトランザクションの先頭にいくつのブロックがあるか)にアクセスして、同じことを別のビューとして実行できます。 例えば、トランザクションがブロックに現れた直後の深さは1であり、実行される作業は現在のネットワーク速度に依存します。 1時間後、平均では6ブロックになるはずですが、実際はかなり異なります。トランザクションの信頼リスナーは新しいブロックが受信されるたびに実行され、リスナーを登録し、信頼レベルに達した時に、それを使用して商品やサービスを提供することができます。

「再編成」とは、チェーンが分岐し平行に走っている時に、一方のチェーンに置き換えられる事で起こります。再編成は、過去に確認された取引を未確認または無かったことにすることで、ウォレットに変更が生じます。トランザクションがなかったことになる再編成は、Satoshiの論文で議論されています。再編成されていないFinney攻撃とはわずかに異なります。再編成がチェーンの深いところにあるトランザクションの信頼性を変えることは非常にまれです。

ブロック内にトランザクションが表示されただけでは、有効であるとは限りません。bitcoinjアプリはトランザクションの有効性を確認しません。代わりに、無効なブロックを含むブロックチェーンを構築することは難しいと考えています。なぜなら、自分以外のマイナーのハッシュパワーを凌駕しなければならないからです。しかしこの仮定を悪用される攻撃が1つあります。それは攻撃者がBitcoinネットワークへの接続を制御することです。新しく発見された正当なブロックを見つけることを妨げ、偽物のトランザクションを含む攻撃者の無効なブロックをマイニングすることが出来ます。この攻撃は検出可能です。攻撃者がネットワークを突破できない限り(51%のハッシュパワーを保有しない限り)、新しいブロックが到着する速度が大幅に低下するためです。将来、bitcoinjは怪しいと思うものにフラグが立てられる「赤いアラート」モードを提供するかもしれません。それはあなたのアプリの取引を止める時が来た時です。

高額なサービスを提供している場合、どれくらいの信頼を必要とするでしょうか?従来の経験則から言うと6ブロック、つまり1時間です。もう1つの方法は、現実的にどれくらいの時間待つことができるか理解する事です。その時間内にどれくらいの作業が平均で行われているかを調べ時間の経過とともに攻撃者が不正なマイニングをする関心をなくし、二重払いの攻撃を行うコストが不正をしないマイニングの作業と同じであることを保証します。

フルブロックボディなしでブロックに含めることを証明する

ウォレットに関連する取引を見つける2つの方法があります。
1つ目はフルブロックのコンテンツをダウンロードし全てのトランザクションをスキャンする方法です。しかしこれは非効率的です。大量のデータはダウンロードされるだけで破棄されます。
2つ目はリモートノードから、パターンに一致するトランザクションを要求する方法です。リモートノードがBloomフィルタをサポートしているときに使用します(v0.8以降)。これはブロックの完全なコピーを持っていないのに、受け取ったトランザクションが実際のブロックチェーンにあるかどうか、どのように知ることができるのかという疑問につながります。

ブロックには、トランザクションのリストが順番に格納されています。このリストから、マークルツリーが計算されます。この構造は、マークルルートを生成します。これは、ブロックヘッダーに配置される単一のハッシュ値です。このアプローチは、トランザクションの連結を単純にハッシングすることよりも複雑ですが、大きな利点があります。そのトランザクションとマークルブランチのみを提供することで、トランザクションがブロック内にあることを証明することができます。ブランチは元のツリーの兄弟ノードを構成するハッシュで構成されています。ノードがブロックヘッダー、トランザクション、ブランチを手渡す場合は、トランザクションが実際にネットワークによって受け入れられ、偽造されている可能性はほとんどないことを自分で確認することができます。ブランチはフルブロックボディよりもはるかに少ないスペースなので、これは大変効率的です。また、複数のトランザクションでは、マークルブランチを組み合わせて効率を上げることができます。