デジタル署名|詳解ビットコイン③
『詳解ビットコイン』(Kalle Rosenbaum著、オライリージャパン)を読んでいます。その個人的なまとめとして書いていきます。
デジタル署名が解決する問題
デジタル署名は、なりすましの問題を解決します。
前提として、ビットコインネットワークを使って送金をするには、送金者が送金に関する情報(トランザクション)を作成し、ビットコインネットワークに送る必要があります。
もし何も対策がされていなかったら、トランザクションを作った人がBTCの保有者本人かどうかが分かりません。そのため、悪意のある者が他の人になりすまし、資産を盗むことができます。例として、メリッサがジョンになりすますケースを考えます。メリッサはジョンのふりをして、ジョンのBTCを自分宛に送るというトランザクションを作ることで、ジョンのBTCを盗めてしまえます。
ビットコインネットワークを使うのに本人確認は不要ですので、もし対策がされていなければ、怪しい人物が複数のアカウントを作って、不正送金を試みようとしたかもしれませんし、犯行が起こった後に犯人を特定するのは困難だったでしょう。また、ビットコインネットワークでは一度承認された送金は基本的に元に戻せないので、被害者が後日気づいたとしても、その不正送金をキャンセルしてもらうことはできなかったでしょう。
なりすましによる被害は、防がなければいけません。ビットコインはそのために、デジタル署名を利用しています。
秘密鍵で署名を作り、公開鍵で検証する
デジタル署名の説明は、p.47の監訳コメントが非常にわかりやすいと感じました。コメントの一部をそのまま記載します。
上記のとおり、デジタル署名は2つのプロセスに分けることができます。秘密鍵を使った署名の作成と、公開鍵を使った署名の検証です。
ビットコインではユーザーが署名を作り(実際にはウォレットアプリが自動的に作成)、ノードが検証するという分担でデジタル署名を実行します。なりすましを検知するのはノードの仕事です。適合する秘密鍵での署名が確認できなかったなら、なりすましの可能性があるので、ノードは検証後にトランザクションを廃棄します。
秘密鍵の管理はユーザーの仕事
ノードが確認してくれるからといって、ユーザーが何もしなくてよいかというと、そうではありません。自分のウォレットの秘密鍵は、ユーザー自身が責任を持って管理しなければいけません。
もし秘密鍵を他人に知られてしまったら、その他人は流出した秘密鍵を使ってなりすましを行えます。このなりすましによって作ったトランザクションは、ノードによって不正とされません。なぜなら、ノードが確認するのは適合する秘密鍵で署名がされているかどうかであり、上記のように秘密鍵が流出したケースでは、他人であっても適合する秘密鍵で署名できてしまうからです。
デジタル署名が作られ、検証されるまで
ビットコインネットワークで、デジタル署名が作られてから検証される様子を確認していきます。
①送金情報をSHA-256にかける
まずはユーザーが、送金額や送信者のビットコインアドレスなどを作り、それをSHA-256にかけます。SHA-256にかけるのは、データの長さを一定値に短縮するためです。
②署名を作成する
ユーザーは、一つ前の手順で作ったハッシュと、ウォレットアプリの中に保管されている秘密鍵を使って署名を作成します。
実際には、ハッシングや署名の作成はウォレットアプリがやってくれるので、専門知識がなくても行えます。
③トランザクションを送る
ユーザーは、送金額と送信者のビットコインアドレス、公開鍵、署名を含めてトランザクションとして、これをビットコインネットワークに送信します。
ユーザーが行う処理はここまでです。この後の処理はノードが行います。
④公開鍵を使って署名を検証する
トランザクションを受け取ったノードは、公開鍵を使って署名を検証します。検証によって、ハッシュが得られるというイメージです(ここは真偽不明)。
⑤送信情報をSHA-256にかける
その後ノードは、送金情報をハッシュします。これは①の手順でユーザーが行った処理と同じです。
一つ前の手順(④)でもハッシュを取得しましたが、④と⑤では、異なる方法でハッシュを取得している点がポイントです。
⑥一致したなら合格としてピアに伝達
④で取得したハッシュと、⑤で取得したハッシュを見比べます。それらの一致が確認できれば合格とします。
合格となったトランザクションは、隣接するノード(ピア)に渡されます。
そもそも公開鍵・秘密鍵とは
そもそも公開鍵や秘密鍵とは、どのようなものなのでしょうか。それぞれがどのように生成されるのか、またどのような役割を持つのかについて見ていきます。
生成方法
まずは秘密鍵が作られ、秘密鍵をもとに公開鍵が作られるという流れになっています。
秘密鍵は、乱数生成器(Random Number Generator)を使って作られます。乱数生成器とは、規則性や再現性がない数値(乱数値)を生成できるツールのことです。乱数生成器で作った256ビットの乱数値が秘密鍵となります。
公開鍵は、秘密鍵を関数で処理した結果です。この関数は公開鍵生成関数と呼ばれるもので、暗号学的ハッシュ関数同様に一方通行の関数です。つまり、秘密鍵(入力)から公開鍵(出力)を算出することはできますが、公開鍵(出力)から秘密鍵(入力)を割り出すことは現実的に不可能です。
ビットコインは、ECDSAという関数を公開鍵生成関数として用いています。
役割
秘密鍵と公開鍵には、二通りの活用方法があります。一つは、秘密鍵で署名を作って、公開鍵で検証するという方法です。これはビットコインのデジタル署名にも使われています。
もう一つは、公開鍵でメッセージを暗号化して、秘密鍵で復号するという方法です。これは公開鍵暗号方式と呼ばれる方法です。よりメジャーな方法ですが、ビットコインでは使われていません。
いずれの方法を行う上でも、公開鍵は他人に知られても問題ないですが、秘密鍵は他人に知られてはいけません。
乱数生成器の種類について
乱数生成器は、真性乱数生成器(True-Random Number Generator)と疑似乱数生成器(Pseudo-Random Number Generator)に分けられます。
真性乱数生成器
真性乱数生成器は、物理現象を利用して規則性がない数値を生成するツールです。例えば、サイコロやコインを投げた結果を利用したり、ノイズを発生させている熱振動の挙動を利用したりします。
真に規則性がない数値を生成できますが、生成するのに時間と労力がかかります。
疑似乱数生成器
疑似乱数生成器は、乱数値のように見える数値を生成するツールです。特定の計算をしたり、特定の位置の数値を抽出したりして生成します。代表的な生成方法には、「平方採中法」「線形合同法」などがあります。
コンピュータを用いた乱数生成では、素早く生成を行えますが、真の乱数を得られないとされています。ただし、真の乱数でなくとも十分実用的である可能性があります。