前置き
EthereumのコントラクトwalletといえばMetamaskが有名ですが、この記事ではそれに代わると注目されている新しいwallet、Authereumについて技術的な側面から情報をまとめたものを書きました。
Ethereumやwallet、スマートコントラクト、公開鍵暗号については知っているものとして話を進めます。
Metamaskとの違い
最大の違いはMetamaskはChromeなどの拡張機能という形態をとっているのに対し、AuthereumはWebアプリという違いをとっています。
これによりMetamaskと違ってAuthereum walletではブラウザが使えるすべての端末で利用することができるため、スマホからでもコントラクトのトランザクションを起こすことができます。
また、Metamaskは内部に秘密鍵を暗号化して保持しておきそれをパスワードで複合化して利用するという方法をとるのに対し、Authereumの場合はパスワードを用いて暗号化した秘密鍵をコントラクトに保持して方法をとります。
そのためMetamaskは新しい端末での利用の際に秘密鍵をインポートする必要がありますが、Authereumの場合は新しい端末でもユーザー名とパスワードを知っていれば自分のアカウントにアクセスできます。
ただしAuthereumの場合はアカウント生成時以外にコントラクトに暗号化された秘密鍵を登録する方法がないため、Authereumに既存の秘密鍵をインポートすることはできず新しいアカウントを作る必要があります。
Admin Keys
Authereumのアカウントを管理する鍵です。通常のEthereumアカウントの秘密鍵に相当しますが、複数作成することが可能です。
この鍵が第三者に知られるとアカウントの資産に自由にアクセスできてしまうので、Admin Keyは絶対に秘匿しなければいけません。
Admin KeyはほかのAdmin Keyを作成したり、削除したりすることができます。また通常の秘密鍵のようにLedger Nanoなどのコールドストレージに保管することも可能です。
Admin Keyの作成
Authereumのアカウント作成時に必ず1つ作成されます。作成にはユーザーのブラウザの疑似乱数生成APIの Crypto.getRandomValues()
を利用します。
Crypto.getRandomValues()
はMath.random()
と違い暗号強度の強い乱数値を取得するためのAPIです。
作成されたAdmin Keyは accounts.authereum.org
下のlocalstorageに保存されます。ここには秘密鍵が生の状態で入っていますが、localstorageは同一ドメインからのアクセスしか許可していないため、ほかの悪意のあるドメインのスクリプトが生の秘密鍵にアクセスすることはできません。
またAdmin Keyはパスワードを基にした暗号化用の鍵で暗号化され、Authereumのサーバーに保存されます。またユーザーのパスワードもソルトを加えてハッシュ化されAuthereumのサーバーに保存されます。
ログイン
ログインが必要なのは、先ほど述べたaccounts.authereum.org
下のlocalstorageにAdmin Keyが保存されていない場合です。
ログインではユーザーは登録したユーザー名とパスワードを入力します。
Authereumアプリはパスワードを基に認証を行い(クライアントでダイジェストを生成し、先ほどのダイジェストと一致するか確かめる? 要調査)、認証が通った場合はパスワードを基に暗号化された秘密鍵を返します。 ユーザーはそれを複合化して秘密鍵を取得します。
ログインすると、AuthereumコントラクトはChallengeという文字列を生成しユーザーのAdmin Keyで署名させSession Tokenとします。以後ユーザーがアカウントの残高などの情報をリクエストしたいときはこのSession TokenをethwebtokenというJWTに似た形式でリクエストとともに提出し、Session Tokenが正しいなら情報がレスポンスとして帰ってきます。
Dapp Keys
Dapp KeyはサードパーティのDappがトランザクションを発行する際の署名のために使われる一時的な鍵です。
Dapp Keyが発行されるまで
Dapp Keyが発行されるまでのフローはOAuth2のインプリシット方式のフローとよく似ています。
ユーザーがDappでAuthereumのウォレットを使うなんらかの操作をすると、OAuth2形式の認証と同様にauthereum.org(このドメインはadmin keyにアクセスできます)へリダイレクトされるか、ポップアップが出現します。
そこでユーザーが、DappがAuthereumにアクセスすることを承認する(OAuth2では連携を許可するに相当します)ことでDapp Key(Login Keyとも呼ばれます)とDapp KeyのHashにAdmin Keyの署名のついたattestation(OAuth2でいうアクセストークンに近いもの 承認されたことを表す)が作成され、元のページに戻されます。
生成されたattestationは、OAuth2のアクセストークン同様に有効期限やトランザクションが有効なスコープがあるためDapp KeyはAdmin Keyと比べて権限の小さい認証情報になっています。
Dapp Keyを用いてDappのトランザクションを実行する
Authereumはcontract-based accountという通常のEOAとは違うアカウント形態のためトランザクション発行の手順が少しことなります。
アカウントの実態はAuthereumコントラクトによって管理されているため、Dappのトランザクションを引き起こすにはAuthereumコントラクトにDappのトランザクションを起こしてもらうように委任する必要があります。(Meta transaction)
このためDappのトランザクションを実行するためには、実行したいトランザクションにDapp Keyで署名したものに加えて先ほどのDapp Key発行の際に生成されたattestationも付与してAuthereumコントラクトに送信する必要があります。
このときDappのトランザクションを実行するためのgasは付与する必要はありません。
Authereumコントラクトは、この署名と付与されたattestationの検証を行いクリアした場合はDappのトランザクションを必要なgasを付与して発行します。
このようにしてDappのトランザクションは実行されます。
まとめ
Authereumについて、技術的な側面から認証に重きを置いた解説記事を書きました。
ほかにもアカウントのリカバリなどAuthereumにはまだまだ特筆すべき機能があるため今後もこの記事を加筆していく予定です。
僕もAuthereum公式のドキュメントを調べながら記事を書いたので間違ったところがあるかもしれません。もし見つかったら優しく指摘してくださると助かります。
参考
Authereum: Improving Authentication on Ethereum
Authereum Key Architecture Explained