ライトニングノードのメジャーな実装のひとつにLNDがあるのですが、LNDは外部アプリと連携するためのAPIが標準搭載されていることもあり、LNDをウォレットの実態として利用するようなモバイルウォレットアプリなどが登場しています。
ライトニングノードは仕組み上オンチェーンの秘密鍵を保有しており、ある意味ホットウォレットと捉えることもできます。そうなると、リモートから不正にアクセスされてしまうのでは、とセキュリティが気になりますね。
今回は、LNDで外部アプリと連携する際に使用されている認証と認可メカニズムである「Macaroons」について解説します。
背景
LNDは外部アプリと連携するためにgRPC APIを公開することができます。ですが、単純にAPIを公開すると世界中の誰とも分からない人からアクセスされてしまいますので別途ファイアウォール的なセキュリティで守る必要があります。このへんは、2016年夏ごろに課題視されていたようです。
このGitHub Issueによると、認証方式としてPassword Hash方式、Macaroons方式の2つが提案されていたようです。
Password Hash方式
いわゆるパスワードで守る方式です。とてもシンプルなことが強みでもあり弱みでもあります。API命令ごとにサトシ数量指定に制約を課す、といった柔軟な制御はできません。
Macaroons方式
とても柔軟な制御ができますが、先進的で採用事例に乏しいです。
ウォレット形式ですら独自方式を採用しているLNDです。こういった場合、いかにも後者を採用しそうですね。はたして2017年1月、Lightning LabsはMacaroonsを導入する方針だと表明し、同年8月には実装しました。
Macaroonsとは?
Macaroonsは、分散システムでの認証と認可に使用される柔軟性の高いトークンベースの方法で、Googleを含む著者陣が2014年に公開した研究論文がオリジナルです。
Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud
Macaroonsは、いわばHMACチェーンといった構造をしています。
HMACというのはHash Based Message Authentication Codeのことで、認証及び改ざん検出に使われる暗号技術のひとつです。普通のSHA256といったハッシュ関数だとデータだけが入力であるのに対し、HMACではデータと秘密鍵とが入力になります。
ハッシュ値 = SHA256(データ)
HMAC値=HMAC(秘密鍵, データ)
HMAC自体にはデータの暗号化機能はないのですが、改ざんを検知することができます。例えば、気心の知れているとある2人がデータを安全に(途中で改ざんされずに)やりとりしたいという状況を考えます。この2人は秘密鍵(あるいはパスワード)を事前に共有しておきます。
データを送付する際に、データそのものとそのHMAC値(タグといったりします)とをセットにして送ります。秘密鍵を共有している受信者は、受け取ったデータと秘密鍵からHMACを計算し、受け取ったタグと一致するかを検証することでデータが改ざんされていないかを確認できます。
さて、Macaroonsでは、こうしたHMACを重ねてAPI認証用のトークンを構成します。この重ねる感じがお菓子のマカロンを感じるからのネーミングなんでしょうか。ところで、API認証には昔からCookieというものが利用されてきました。お菓子繋がりでちょっとお洒落ですね。
にしても、ライトニングネットワークでのオニオンルーティングといい、プライバシーテックは重ねるものばかりです。
ちょっと横道にそれましたが、HMACを重ねるとはどういうことでしょうか。
Macaroonsでは権限の制限をトークンに課して新たなトークンを再生成することを可能としています。
例えば、なんでもできちゃうAdminトークンを最初につくり、それにこのトークンを利用できるのはIP=192.168.1.1なクライアントだけだよ、という制限を付けることができます。
まず、適当な乱数R、秘密鍵Sを用意します。これを使ってAdminトークンを生成します。
H1 = HMAC(S, R)
Adminトークン = { R, H1 }
次に、IP制限C (IP=192.168.1.1)をつけます
H2 = HMAC(H1, C)
IP制限トークン = { R, C, H2 }
このように一つ前の層のHMAC値を新たな層での秘密鍵として利用し、HMACを計算します。秘密鍵を知っている主体だけがこのHMACの連なりを順に辿ることで検証できます。
HMACを重ねるという技により、アクセス制御のための条件付き委任が実現できました。
IP制限トークンを受け取ったユーザーは、元のAdminトークンに戻すことができない点がポイントですね。