はじめに
RaspberryPi(以下、RPiと略します)で動く IoT なプロダクトを作って評価用に貸し出し致しましたら、後日、展示会で先様の自社開発製品として展示されているのを見てズッコケた経験をして以来、提供する時はかならずCopy Protection を入れるようにしています
幸い、RPi の場合は SD カードやボードそのものの固有ID、内蔵や増設の NIC のアドレス等、端末を特定できるいろいろな ID を読むことができますので、例えばアプリの起動時に SD カードの ID を読んで、貸し出した SD の ID と違ったら即 exit する一文を先頭にいれておくといういささかカジュアルな方法でもコピープロテクトが実現できます1。粗末な鍵でもあるだけで防犯効果が桁違いなのと同様、こんな素朴なプロテクトでもかなりの効果がございますので諸兄諸姉にもお薦めいたします次第にございます
そもそもセンサーを読んでサーバーに投げるようなプロダクトだと、SDカードを丸々コピーして別のボードで起動するだけでなりすまし端末ができてしまうという脅威がございます
これを使って嘘データ、例えば400℃なんて温度を送ってこられると火事だと思ってスプリンクラーに水まかれたりしそうですし、植物工場で低いCO2濃度を送り続けられたりするとCO2施肥が止まらず死亡事故というか殺人事件に利用されかねないと思います
暗号化ストレージで保護するのってこれに対してまるで無意味で、起動時の復号化の処理がそのままコピーされいるので、起動シーケンスを通じて普通に復号化して普通に起動してしまいます
基本的に悪意のコピーが起動しないようにガードを入れておかなければいけない筈なのですが、いくつかのフレームワークを見てきたのですがガードのための機能が提供されているものは見たことがなくアプリの責任でガードしなさいってドキュメントに露骨に書いてあるのさえございました
これが、誰でも気軽に使えるコピープロテクションのサービス、IoT のアプリでも有効に保護する Koshitno を作って公開させて頂きました理由でございます
Koshitno サービスと Sansi ライブラリ
そんなわけで作ったのがKoshitno サービスです。RPi だけではなく、一般の Linux と Mac でも使える汎用サービス2なのでございますが、本稿では RPi の観点でご説明させていただきます次第です
使い方の詳細等、一般的なお話はまた別のアドベントのこちらの記事でご紹介させていただければと存じております
No license file な copy protection
ストレージが隙だらけな IoT 端末なのにストレージに license file や credential を置く事の危険を危惧して Koshinto は No license file というあまり類をみない仕組みでアプリケーションの anti-piracy を実現します
ライセンスファイルがないおかげで使い方はとても簡単で、Koshinto にログインして、ライブラリの Sansi をダウンロードして自分のアプリに組み込む だけでできあがり
ライセンスファイルというややこしい、事故の原因になりやすい、攻撃の対象になりかねないものの申請・発行・配布は使わないので不要です。単に sansi を組み込んだアプリケーションを1度起動するだけで、そのアプリケーションの起動をその環境に限定する事ができます
あなたのアプリのユーザーはあなたから提供されたアプリを使うことはできてもコピーはできません
No license file な Copy Protection のしくみ
アプリケーションが実行の可否の判断に利用する各種環境の情報、では長いので適当な名前をつけて「Bind」と呼ぶことにします。アプリケーションの束縛ってイメージでそう命名します。Bind の実態は SD Card の ID だったり RPi ボードの serial number だったり、MAC adress だったり IP Address だったり、そういう起動環境を特定することに使える情報の集まりです。Bind は一意な ID で管理し、これを Bind_ID と呼びます
従来の Copy Protection の実装では Bind はライセンス・ファイルに保存されていましたが、Koshinto では代わりにそれをサーバに保存します
Sansi ライブラリはアプリに confirm()
という関数を提供します。confirm()は呼び出されると各種の環境情報を収集して、Bind_ID をつけて Koshinto にお伺いをします
Koshinto は、送信された Bind_ID に対応する Bind と、Token の中の各種環境情報を鑑みてOKもしくはNGの返答のための Token を返します
アプリケーションは confirm() からの返り値が OK だったら処理を続行、NG だったら exit すれば、これでアプリケーションの実行を Bind に指定された条件に制限することができるわけです
Bind_ID は Sansi ライブラリの中にobfuscate して埋め込んでありますので、ユーザーが気にする必要はありません
つまり、以下の3点の設計上の工夫でライセンス・ファイルをなくしています
- Bind 情報をライセンス・ファイルではなくサーバに保管
- アプリにリンクするライブラリ自体がクレデンシャルを兼ねる
- ライブラリの取得は Bind の所有者のみにシステムで制限
尚、大規模な利用等で個別のライブラリをつどダウンロードしてリンクするのがどうしても現実的でない場合は、従来のライセンスファイル等を指定する方法も用意してありますので、アプリがスケールいたしましてもご安心ください。しかも、その場合でさえ従来の商用サービスよりかなり簡単に作れるようになっていると自負しております3
koshinto と sansi の特徴
out-of-the-box
Koshinto にアカウントを作って、Bind を選択して sansi をダウンロードして自分のアプリに組み込めばインプリメンテーションはこれでおしまいです
Bind に指定する SD Card ID や RPi の固有IDなども自分で調べる必要はありません。鍵の設定は confirm() の初回の起動で Koshinto に送られてくる情報をただ鍵として選択するだけでOKです。もちろん、ご存知なら直に指定してもかまいません
これで Copy Protection は完了!アプリケーションは 02544… の SD カードから、かつ 00…858229a0 の RPi ボードからしか起動できなくなりました
商用の Anti-Piracy だとライセンスファイルだのキーコードだのの申請みたいな話がある以前にそもそも営業の人に客だと思ってもらわなければならないという障壁が待っていて、ボリュームが見込まれるアプリケーションでないと相手してもらえないでしょうし、評価用に貸し出すプロダクトをガードしたいとか言うと塩まかれて追い返されそうですが、Koshinto はどなたでもご自由にご利用いただけます
最初に confirm() してきた環境に自動的に束縛するような簡易な使い方も可能です4
forfeitable
束縛情報をサーバー側でもっておりますので、提供した先様のおやらかしが発覚した時には権限をその場5で無慈悲に剥奪することができます
人の足元を見てしょうもないことをしそうな相手を相手にせざるをえない場合でも、これで泣き寝入りは不要などころか逆に悪者を泣かす事さえ可能であるという、まさに弱者を強者に逆転させるサービスであると自負いたしております次第にございます
secure
束縛情報はネットワークで隔離されたセキュアなサーバにありますので、ライセンスファイルを開くためのキーが漏れてライセンスが改ざんされてしまった、という世間でよく聞く話が原理的にございません
でも、Anti-Piracy サービス自身が tamper されて改ざんやなりすましされるようではシャレになってないですが、詳細はセキュリティーのアドベントのこちらに詳しく書きますが、カジュアルアタックぐらいには十分耐えうる実装になってるんじゃないかなと思ってます
affordable
誠にささやかで恥ずかしい次第なのですがアカウントに一つ無料の Bind がございますので、アプリケーションの評価用の貸し出しなどの目的などにお気軽に使い回していただければ幸いです。Bind は初期化できますので何度でも使い回しが可能です
同時に複数の Bind が必要になる場合につきましては、リソースを賄うために大変恐縮で心苦しい次第ではございますがご購入のお願いさせて頂いておりますが、こちらも affordable に徹します所存にございます
むすび
気軽に使える Copy Protection なのでお気軽に使っていただければと存じます。冒頭でも述べました通りなりすまし防止は本質的に必須な要件だと思いますし、ノーガードなサンプルを提供して結果として相手と気まずくなるのもつまらないので Copy Protection をお忘れなく
related works
この種の anti-piracy なサービスでは古くから FLEXlm が有名で、私も 90' に自社製コンパイラにコピーガードとして組み込む側で使ったことがあります。類似の商用サービスがいくつかあるようです
探してみたのところ、営業を通さなければならないものばかりで、私のような野良犬でも気楽に利用できるものでもなさそうでした
また IoT 端末での使用について言及しているものはみつけられませんでした
プロダクトの性質上、オープンソースはないだろうと思っていたのですが、しらべてみたら[Open License Manager]
(https://github.com/open-license-manager)というオープンソースで copy protection を実現しているプロジェクトがあるようです。どういう理屈で自身を tamper から防ぐことができているのか興味があります
Our Contributions
いくつもの Copy Protection の実装がすでに世の中に存在する中においてエマージングなIoT 端末がストレージの脅威下で利用される事が多いが故に想定されうる危惧に対し、 No license file 構成を提案し、Koshinto として実装を行い、広く利用できるサービスとして提供した事、ならびにそれを広く紹介した事が、コミュニティに対する本稿の貢献であると著者は考える、って論文調6で偉そうにしてしまってどうもすみません ^^;;;
名前の由来
Sansi は蚕糸でも参詣でも三枝(文枝になっちゃいましたね)でもなく三尸と書きます。庚申信仰という、西日本では平安時代に、東日本では江戸時代に大流行したらしい体の中に潜む三尸虫が庚申の日の夜にその人の悪事を閻魔に告げ口にいくという信仰に由来しております。オリエンタルなネーミングで西海岸のIT屋さんへの受け狙いがにじみ出てます。姿はこんな感じで可愛らしいです。右から上尸、中尸、下尸といって、それぞれ頭、お腹、下腹部にに潜んでいて、庚申の日の夜中に出てくるらしいのですが、その情景を想像すると鴨川ホルモーみたいでスリリングです。持ってる巻物に主の悪事がすべて記載されてるのだそうですが、私だったら何書かれてるんだろ
でも、庚申の夜に主が頑張って寝ないで起きてると三尸は出てこれないで死んでしまうそうです。なので、庚申の夜には皆で集まって、飲んで歌って(逆効果な気がするんだけど)徹夜して、三尸が出てこれないようにしてたんだそうで、これを庚申講というのだそうです。こんな朝まで宴会の言い訳みたいな信仰、そりゃ流行るよな
告げ口虫とはいえ殺めてしまうのは可愛そうなので、庚申塔を建てて供養したのだそうです。これぞ Kosinto の由来にございます。わたくしの蟄居致します多摩丘陵のまさに端っこの、久本山近辺では江戸時代に野菜(城下では常に不足していたそうです)の出荷でそれはもう大変豊かだったそうで、悪徳坊主の怪しげな話に騙されたリッチなお百姓様も多かったらしく、やたらと庚申塔が多いことにポケゴしてて気が付きました次第です
references
- セキュリティのアドベントに Koshinto 自身の anti-tamper について書きました
- 個人開発のアドベントに個人開発なさってる方に気軽に使っていただけるような観点で記事を書きました
- Koshinto Docs Koshinto のドキュメント
- Koshinto Koshinto サービスの入り口
- Sansi_Example アプリケーション への Sansi の組み込み方の言語毎の解説とサンプル。現在、c, go, python, bash の例を用意しています
- 庚申信仰 蛇足ながら Wikipedia
明日は
2020年 RaspberryPi アドベント、明日はt-matさんの「ラズパイZeroとWebSocketとサーバーでCNNカメラ的なものを作ってみる」です、これは楽しみですね!