なぜ「最後の結果をキャッシュするだけ」では本当に機能しないのか
分かりやすい修正方法は、最後に成功したチェックをローカルファイルやレジストリに記憶しておき、次回はネットワーク呼び出しをスキップすることだ。それはオフライン問題を解決するが、何も検証していない——それはディスク上の文字列にすぎず、テキストエディタを持つどんなユーザーでも false から true に切り替えられる。それはきれいに期限切れにもならず(コピーされたファイルは2台目のマシンで永遠に動作する)、実際に最後にいつ検証されたのかを教えてくれない。あなたは「オフラインサポートなし」を「実際にはチェックですらないオフラインサポート」と交換しただけだ——そのファイルは信頼されているだけで、検証されていない。
なぜ本物のオフライン検証を自作することがフラグをキャッシュするより難しいのか
本物のオフライン検証とは、アプリがサーバーに問い合わせることなく、そのサーバーからしか来ようがないデータだけを使って、ライセンスが有効であることを証明できなければならないということだ。それには秘密鍵/公開鍵のペア(サーバーが署名し、アプリは公開鍵の半分だけを持つ)、ライセンスキー、マシンID、そしてアプリが時計と照合できる有効期限を含むコンパクトな署名済みペイロード、改ざんを検出可能にする方法——1バイトを反転させれば署名が必ず失敗するようにする——そして、アプリが再びオンラインで問い合わせを強制されるまで、古いが署名済みの結果をどれだけ信頼し続けるかという判断が必要だ。これらはどれもエキゾチックな暗号技術ではないが、それを正しく組み上げること——ペイロードを解析する前にまず署名を検証し、その中のすべてのクレームをチェックし、妥当な有効期限のウィンドウを選ぶこと——は、一度だけ微妙に間違えて、それに気づくことが決してないタイプの類のものだ。
署名付きリース:サーバーが署名し、アプリは検証するだけ
これがまさに SublimeKeys のオフライン検証がやっていることだ。すべての activate/verify 呼び出しはリースを返す——ライセンスキー、マシンID、製品ID、そして7日間有効な有効期限を含む、小さな Ed25519 署名トークンだ。あなたのアプリはそれをローカルにキャッシュし、あなた自身のバイナリに同梱された公開鍵に対して署名を検証する——秘密鍵は決して私たちのサーバーから出ないので、ユーザーのディスク上には有効なリースに書き換えられるものが何もない。改ざんされたリースは、その内容が解析される前ですら、署名検証で即座に失敗する。7日間のウィンドウが経過すると、次のチェックは静かにオンラインになり、新しいリースを取得し、サイクルが繰り返される——こうして完全にオフラインのマシンは一度に最大1週間、検証可能にライセンスされ続け、失効したライセンスはマシンが次に再接続したときに捕捉される。
追加方法——公式SDKで3ステップ
実際に何が手に入るのか
あなたのアプリは、通常の日にはネットワーク呼び出しゼロでマイクロ秒単位でライセンスを検証し、1週間の機内モードや封鎖された企業ネットワークの中でも正しく動作し続け、それでもマシンが再接続してから7日以内に失効または返金されたライセンスを捕捉する——暗号技術を自分で一行も書かず、鍵管理システムをホストせず、誰かがいずれ編集する方法を見つけてしまう独自のトークン形式を発明することもなく。
実際に誰のためのものか
出張の多いユーザー
コンサルタント、フィールドエンジニア、ラップトップが飛行機やクライアント先で実際にオフラインの時間を過ごす人すべて。
封鎖された企業ネットワーク
明示的にホワイトリストに登録されていないものへのアウトバウンドAPI呼び出しをブロックするファイアウォールの背後にあるマシン。
Pythonデスクトップツール
pip install sublimekeys——オフライン検証が公式SDKに組み込み済み。
Electronアプリ
npm install sublimekeys——同じ署名リース検証、ネイティブ依存ゼロ。
エアギャップ / 規制対象環境
そもそもインターネットに到達すべきではなく、時々同期するだけのマシン。
About
Patrick Chen —— Sublimearts.io の背後にいるインディー開発者。出張ユーザーや企業ユーザーに販売されるすべてのデスクトップアプリが、いずれ同じ「インターネットなし」の壁にぶつかることに気づき、SublimeKeys にオフライン検証を組み込んだ。
Did you find this helpful?