前回は未達に終わっていたのですが、ようやく完成しました。
WebAssemblyとは?
WebAssemblyというのはWebブラウザ上で動作するプログラミング実行環境です。JavaScriptとは異なり、コンパイルするのが大きな特徴です。コンパイルすると言うことは、コードの中身が見られないということです(テキストへのコンパイルも可能です)。WebAssemblyはコンパイルすることでJavaScriptのように実行時にコードを解析、コンピュータ用のコードに変換する必要がなくなるので、実行も速くなります。
何が嬉しいのか
今回の目的で言えば、コードの中身が見られなくなると言うのが大きな利点です。これによってNCMBの「署名生成処理」が隠せるようになります。署名に使われるクライアントキーを WebAssemblyのコードの中に入れてしまうことで、漏洩するリスクが減らせます。
2020/06/24追記:WebAssemblyで生成されるバイナリは難読化レベルであって、テキストへのコンパイルでキーが閲覧できるリスクは残ります。WebAssemblyによる署名作成処理はあくまでも平文よりは漏洩リスクが下げられる程度です。データの操作時にはACLを設定する、クラス単位での操作権限を設定することで不正なデータ操作を回避できます。
解決しない問題
なお、署名処理だけを隠蔽化しているので、ユーザが任意のAPIを叩けるという状態は変わりません。ACLはきちんと設定する必要がありますので注意してください。
Webアプリケーションで使った場合
これまでのニフクラ mobile backendをWebアプリケーションで使った場合、アプリケーションキーとクライアントキーが平文な状態でした。WebAssemblyにすることで、クライアントキーが隠蔽化されます。通信自体はこれまでと変わらずAjaxを使いますので、ネットワークを監視することでどういったデータ操作が行われているかは分かってしまいます。JavaScript SDKの使い方をしっているユーザであれば、データ操作も可能でしょう。ただしACLが正しく設定されていれば、Webアプリケーションと同レベルのセキュリティが担保されます。
使い方
JavaScript SDKへの組み込みは若干複雑なので別記事で紹介します。今回はWebAssemblyとしての使い方を紹介します。
Rust/Cargo環境のセットアップ
今回はRustを使って開発しています(WebAssemblyはRustの他、C/C++/C#などでも開発できます)。Rustupを使うことでセットアップやバージョンアップが簡単になります。
rustup.rs - The Rust toolchain installer
そしてRustでWebAssemblyの開発環境を整える方法について、Rust単体でWebAssemblyをコンパイルする(Emscripten無し)が参考になります。 wasm32-unknown-unknown
というターゲットを追加するのがコツです。
コードをcloneする
次に NCMBMania/wasm をクローンします。
$ git clone git@github.com:NCMBMania/wasm.git
コードを編集する
src/lib.rt
の中にあるクライアントキーを編集します。
let key = "YOUR_CLIENT_KEY";
コンパイルする
Rustのコードをコンパイルします。コンパイル後、ルートディレクトリに ncmb.wasm が生成されます。
$ make all
利用法
基本的な使い方が index.html / script.js に書いてあります。これは入力された文字を署名して返却するコードです。WebAssemblyのコードはエクスポートしてしまえば、同期の関数として利用できます。
let a = document.querySelector('#a'), b = document.querySelector('#b'); fetchAndInstantiate('./ncmb.wasm') .then(mod => { exports = mod.exports; let to_sign = s => { let outptr = exports.to_sign(newString(exports, s)); return copyCStr(exports, outptr); }; a.oninput = () => b.value = to_sign(a.value); });
なお、利用時には file:///
として開いても動作しません。HTTPサーバからアクセスする必要があるので注意してください(ワンライナーのHTTPサーバでも十分です)。
まとめ
WebAssembly版を使うことでクライアントキーの隠蔽化が実現します。通信が隠蔽化できる訳ではなく、コード全体も隠蔽化される訳ではないので適切なACL設定は必須ですが、アプリケーションキーとクライアントキー両方が平文な状態よりも十分にセキュアでしょう。Webアプリケーションでもニフクラ mobile backendを使える可能性が出てきたと言えそうです。