誰でも気軽につかえる RaspberryPi 用の Copy Protection サービスをつくりました

# はじめに
RaspberryPi（以下、RPiと略します）で動く IoT なプロダクトを作って**評価用に貸し出し**致しましたら、後日、展示会で先様の**自社開発**製品として展示されているのを見てズッコケた経験をして以来、提供する時はかならずCopy Protection を入れるようにしています

幸い、RPi の場合は SD カードやボードそのものの**固有ID**、内蔵や増設の **NIC のアドレス等**、端末を特定できるいろいろな ID を読むことができますので、例えばアプリの起動時に **SD カードの ID を読んで、貸し出した SD の ID と違ったら即 exit** する一文を先頭にいれておくといういささかカジュアルな方法でもコピープロテクトが実現できます[^1]。粗末な鍵でもあるだけで防犯効果が桁違いなのと同様、こんな素朴なプロテクトでもかなりの効果がございますので諸兄諸姉にもお薦めいたします次第にございます

[^1]: ガラケーの昔の SD Bind と同じ理屈ですね

そもそもセンサーを読んでサーバーに投げるようなプロダクトだと、SDカードを丸々コピーして別のボードで起動するだけで**なりすまし端末**ができてしまうという脅威がございます
これを使って嘘データ、例えば400℃なんて温度を送ってこられると火事だと思ってスプリンクラーに水まかれたりしそうですし、植物工場で低いCO2濃度を送り続けられたりするとCO2施肥が止まらず死亡事故というか殺人事件に利用されかねないと思います
[暗号化ストレージで保護する](https://qiita.com/UedaTakeyuki/items/bd7c09c4077914b915af)のってこれに対してまるで無意味で、**起動時の復号化の処理**がそのままコピーされいるので、起動シーケンスを通じて普通に復号化して普通に起動してしまいます
基本的に**悪意のコピーが起動しないようにガードを入れておかなければいけない**筈なのですが、いくつかのフレームワークを見てきたのですがガードのための機能が提供されているものは見たことがなく**アプリの責任でガードしなさい**ってドキュメントに露骨に書いてあるのさえございました

これが、誰でも気軽に使えるコピープロテクションのサービス、**IoT のアプリでも有効に保護する** [Koshitno](https://koshinto.uedasoft.com/docs/) を作って公開させて頂きました理由でございます

# [Koshitno](https://koshinto.uedasoft.com/docs/) サービスと [Sansi](https://github.com/UedaTakeyuki/sansi_examples) ライブラリ

そんなわけで作ったのが[Koshitno](https://koshinto.uedasoft.com/docs/) サービスです。RPi だけではなく、一般の Linux と Mac でも使える汎用サービス[^2]なのでございますが、本稿では RPi の観点でご説明させていただきます次第です
使い方の詳細等、一般的なお話はまた[別のアドベント](https://qiita.com/advent-calendar/2020/private-development)の[こちらの記事](https://qiita.com/UedaTakeyuki/items/90bdafa6d3014673fa93)でご紹介させていただければと存じております

[^2]: Window は開発マシンのドネーションを[募集中](https://github.com/UedaTakeyuki/sansi_examples#not-for)です

## No license file な copy protection
ストレージが隙だらけな IoT 端末なのにストレージに license file や credential を置く事の危険を危惧して Koshinto は **No license file** というあまり類をみない仕組みでアプリケーションの anti-piracy を実現します


ライセンスファイルがないおかげで使い方はとても簡単で、**Koshinto にログイン**して、ライブラリの [Sansi](https://github.com/UedaTakeyuki/sansi_examples) を**ダウンロード**して自分のアプリに[組み込む](https://github.com/UedaTakeyuki/sansi_examples) だけでできあがり

ライセンスファイルというややこしい、事故の原因になりやすい、攻撃の対象になりかねないものの申請・発行・配布は**使わないので不要**です。**単に sansi を組み込んだアプリケーションを１度起動するだけ**で、そのアプリケーションの起動をその環境に限定する事ができます

あなたのアプリのユーザーはあなたから提供されたアプリを使うことはできても**コピーはできません**

## 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 に指定された条件に制限することができるわけです

![スクリーンショット 2020-11-22 12.35.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46544/990c0855-ffe4-28b6-4e21-5d84bbdd65c5.png)

Bind_ID は Sansi ライブラリの中に**obfuscate して埋め込んで**ありますので、ユーザーが気にする必要はありません

つまり、以下の３点の設計上の工夫でライセンス・ファイルをなくしています
- Bind 情報をライセンス・ファイルではなく**サーバに保管**
- アプリにリンクするライブラリ自体が**クレデンシャルを兼ねる**
- ライブラリの取得は Bind の所有者のみに**システムで制限**

尚、大規模な利用等で個別のライブラリをつどダウンロードしてリンクするのがどうしても現実的でない場合は、従来のライセンスファイル等を指定する方法も用意してありますので、アプリがスケールいたしましてもご安心ください。しかも、その場合でさえ従来の商用サービスよりかなり簡単に作れるようになっていると自負しております[^3]

[^3]: 詳細は[こちら](https://qiita.com/advent-calendar/2020/private-development)のアドベントの[この](https://qiita.com/UedaTakeyuki/items/90bdafa6d3014673fa93)記事で

## koshinto と sansi の特徴

### out-of-the-box
Koshinto にアカウントを作って、Bind を選択して sansi をダウンロードして自分のアプリに組み込めばインプリメンテーションはこれでおしまいです

Bind に指定する SD Card ID や RPi の固有IDなども自分で調べる必要はありません。鍵の設定は confirm() の初回の起動で Koshinto に送られてくる情報をただ鍵として選択するだけでOKです。もちろん、ご存知なら直に指定してもかまいません

![ss.2020-11-08 20.38.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46544/8e4edae0-1791-a370-48e7-914127591715.png)

これで Copy Protection は完了！アプリケーションは 02544… の SD カードから、かつ 00…858229a0 の RPi ボードからしか起動できなくなりました

商用の Anti-Piracy だとライセンスファイルだのキーコードだのの申請みたいな話がある以前にそもそも**営業**の人に客だと思ってもらわなければならないという**障壁**が待っていて、ボリュームが見込まれるアプリケーションでないと相手してもらえないでしょうし、**評価用に貸し出すプロダクトをガードしたい**とか言うと塩まかれて追い返されそうですが、Koshinto は**どなたでもご自由にご利用いただけます**

最初に confirm() してきた環境に自動的に束縛するような簡易な使い方も可能です[^4]

[^4]: 詳細は[こちら](https://qiita.com/advent-calendar/2020/private-development)のアドベントの[この](https://qiita.com/UedaTakeyuki/items/90bdafa6d3014673fa93)記事で

## forfeitable
束縛情報をサーバー側でもっておりますので、提供した先様のおやらかしが発覚した時には権限をその場[^5]で**無慈悲**に**剥奪**することができます  
人の足元を見てしょうもないことをしそうな相手を相手にせざるをえない場合でも、これで泣き寝入りは不要などころか逆に悪者を泣かす事さえ可能であるという、まさに**弱者を強者に逆転させるサービス**であると自負いたしております次第にございます

[^5]: iPod Touch の小さな画面でも普通に使えるように UX をデザインしておりますので、出先でも操作に問題はございません

## secure
束縛情報はネットワークで隔離されたセキュアなサーバにありますので、ライセンスファイルを開くためのキーが漏れてライセンスが改ざんされてしまった、という世間でよく聞く話が原理的にございません

でも、Anti-Piracy サービス自身が tamper されて改ざんやなりすましされるようではシャレになってないですが、詳細は[セキュリティーのアドベント](https://qiita.com/advent-calendar/2020/security)の[こちら](https://qiita.com/UedaTakeyuki/items/a3ffb76f51b8daaf8ccd)に詳しく書きますが、カジュアルアタックぐらいには十分耐えうる実装になってるんじゃないかなと思ってます

## affordable
誠にささやかで恥ずかしい次第なのですがアカウントに一つ無料の Bind がございますので、アプリケーションの評価用の貸し出しなどの目的などにお気軽に使い回していただければ幸いです。Bind は初期化できますので何度でも使い回しが可能です
同時に複数の Bind が必要になる場合につきましては、リソースを賄うために大変恐縮で心苦しい次第ではございますがご購入のお願いさせて頂いておりますが、こちらも affordable に徹します所存にございます

# むすび
気軽に使える Copy Protection なのでお気軽に使っていただければと存じます。冒頭でも述べました通りなりすまし防止は本質的に必須な要件だと思いますし、ノーガードなサンプルを提供して結果として相手と気まずくなるのもつまらないので Copy Protection をお忘れなく

# related works
この種の anti-piracy なサービスでは古くから [FLEXlm](https://ja.wikipedia.org/wiki/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]で偉そうにしてしまってどうもすみません ^^;;;

[^6]: [この論文](https://crypto.junod.info/spro15.pdf)みたいに Our Contributions という章を設けて著者が考える価値を客観的に主張してもらうと、読むほうとしても価値の評価の誤解がへるので、シャイな私達には気がひけるところはあるのですが、よい構成だなと思っています

# 名前の由来
Sansi は蚕糸でも参詣でも三枝（文枝になっちゃいましたね）でもなく**三尸**と書きます。庚申信仰という、西日本では平安時代に、東日本では江戸時代に大流行したらしい**体の中に潜む三尸虫が庚申の日の夜にその人の悪事を閻魔に告げ口にいく**という信仰に由来しております。オリエンタルなネーミングで西海岸のIT屋さんへの受け狙いがにじみ出てます。姿はこんな感じで可愛らしいです。右から上尸、中尸、下尸といって、それぞれ頭、お腹、下腹部にに潜んでいて、庚申の日の夜中に出てくるらしいのですが、その情景を想像すると鴨川ホルモーみたいでスリリングです。持ってる巻物に主の悪事がすべて記載されてるのだそうですが、私だったら何書かれてるんだろ
![](https://upload.wikimedia.org/wikipedia/commons/6/69/Taijojo_Sanshi.jpg)

でも、庚申の夜に主が頑張って寝ないで起きてると三尸は出てこれないで死んでしまうそうです。なので、庚申の夜には皆で集まって、飲んで歌って（逆効果な気がするんだけど）**徹夜して、三尸が出てこれないようにしてた**んだそうで、これを庚申講というのだそうです。こんな朝まで宴会の言い訳みたいな信仰、そりゃ流行るよな

告げ口虫とはいえ殺めてしまうのは可愛そうなので、庚申塔を建てて供養したのだそうです。これぞ Kosinto の由来にございます。わたくしの蟄居致します多摩丘陵のまさに端っこの、久本山近辺では江戸時代に野菜（城下では常に不足していたそうです）の出荷でそれはもう大変豊かだったそうで、悪徳坊主の怪しげな話に騙されたリッチなお百姓様も多かったらしく、やたらと庚申塔が多いことにポケゴしてて気が付きました次第です

# references
- [セキュリティのアドベント](https://qiita.com/advent-calendar/2020/security)に Koshinto 自身の anti-tamper について[書きました](https://qiita.com/UedaTakeyuki/items/a3ffb76f51b8daaf8ccd)
- [個人開発のアドベント](https://qiita.com/UedaTakeyuki/items/a2611c27fc89e698be12)に個人開発なさってる方に気軽に使っていただけるような観点で[記事](https://qiita.com/UedaTakeyuki/items/90bdafa6d3014673fa93)を書きました
- [Koshinto Docs](https://koshinto.uedasoft.com/docs/) Koshinto のドキュメント
- [Koshinto](https://koshinto.uedasoft.com/) Koshinto サービスの入り口
- [Sansi_Example](https://github.com/UedaTakeyuki/sansi_examples) アプリケーション への Sansi の組み込み方の言語毎の解説とサンプル。現在、c, go, python, bash の例を用意しています
- [庚申信仰](https://ja.wikipedia.org/wiki/%E5%BA%9A%E7%94%B3%E4%BF%A1%E4%BB%B0) 蛇足ながら Wikipedia

# 明日は
2020年 RaspberryPi アドベント、明日は[t-mat](https://qiita.com/t-mat)さんの「ラズパイZeroとWebSocketとサーバーでCNNカメラ的なものを作ってみる」です、これは楽しみですね！