とはいえ、のっけからで恐縮だが、デジタルデータである以上、不正コピーを 完全に防ぐことはできない。本書の目的は、「可能な限りそのハードルを 上げて、損失を減少させる」こと……を実現するための、 基本の基本をお知らせすることである。
現在、商業・同人含めPCノベルゲーム業界は極めて厳しい状況にある。 DVDメディア含め、個人で手軽にコピー及びネットを通じた違法な頒布が可能な状態であり、 実際これが横行しているためだ。特に商業では、今回の売り上げを次のゲームの 開発費に充てるのだが、この確保が極めて難しくなってきている。
商用エロゲの売り上げ本数がどのくらいかご存知だろうか。まぁまぁヒットと 呼ばれるもので5000本、下手すると2000本に届かないこともよくある。 売上は一本7000円だとすると、2000本なら1400万円。結構あると思うかもしれないが、 実際には、一本の中堅ノベルゲームを作成するのにかかる金額が (勿論ピンキリだが)大体1000〜2000万円と言われているため、本当にカツカツだ。 逆算すると、7人が月20万円で働いて諸費用が一人10万円/月かかり、8ヶ月で ゲームを作り上げるとすると、それだけで既に1680万円。2000本(=1400万円)だと 大赤字になってしまう。実際には他にもたくさん費用(流通・広告など)が がかかるので、赤字幅は更に拡大。
なんでこんなことに?もちろん、「売れるゲームを作る」のが作り手の大前提だ。 ユーザが喜び、感動し、これなら金を払ってよい、と思えるゲームを作り出すための 努力は惜しんではならない。だがしかし、どんなにスバらしい作品を作っても、 それが心無い一部の人々にコピーされ、ネットの海に放流されてしまうとどうなるか。 コピー品を手にした別ユーザは、製品を改めて買おうとはなかなか思わない。 従って、売り上げが低下する。否、「著しく」低下する。
あるメーカーでは、 4000本売れたゲームの、パッチのダウンロード数が35000回だったそうだ。 ユーザが一人2回パッチをダウンロードしたとしても、単純計算で販売本数の 三倍以上(=(35000/(2*4000))-1)の人が、非正規でゲームを入手している可能性が あることになる。これでは次の開発に費用をかけることなどできようもない。 こんな状況だから、新ブランドが初期費用を回収することも極めて困難だ。 だからブランドが雨後の竹の子のように現れ、カビキラーをかけたお風呂のカビの ように消えていく。本当に、冗談抜きで危機的状況にある。
一方、同人界も酷いものだ。元々、同人ソフトでプロテクトや暗号化を施したものは 殆どない。コピーやデータ抽出などし放題の野放図状態。それをいいことに、 頒布開始翌日には、良作が、何の防衛手段も持たないままどんどんネットの海に 放流されていく。結果、せっかく良作を出したサークルの、次が続かない。開発費用が 回収できなかったり、感想を貰えなかったり。いくら同人でも、そのダメージは 図り知れない。 売り上げや頒布数の増加が製作者のモチベーションを著しく向上させるという 特殊事情もある。 伸びえたかもしれない才能が、そこで無残にも潰えていくのを 見るのは本当に忍びない。
やはり、不正コピーを抑止する手段を考えねばならん。そしてそれは、 ゲーム会社やゲームサークルが個別に頭を捻るのではなく、我輩みたいな 一見あまりそういうののステークホルダーではなさそうな人が(基本を)考えた方が、 色々角が立たずに済みそうな気がする。そういうモチベーションで、以下の 文書は作成されていると思って頂きたい。
以下はオマケ。
データ流出はどうなんよ、という話もある。これは直接的には売り上げに関わらない ように思うかもしれない。しかし、 実際には流出したデータを再構成して同等なゲームを他プラットフォーム(例えば PSP)上で遊べるようにしてしまうパワフルな人々がいて、そういう再構成された ゲームが無料頒布されたりすると、やぱり売り上げに関わってくる。また、 シナリオを読ませるゲームなら、シナリオのクライマックスだけが流出 するだけで頒布量に影響するし、エロゲならエロシーンが流出すれば言わずもがな。 加えて、素材を作った人が、「データ流出があったから、もうお前んトコには 素材を提供せん」とか、「今後はもっとお高いお値段で」とか言い始めている。 同人サークルにはかなり厳しい。 だから、我輩は、データ流出も可能な限り防止すべきだ、という立場。
同じ理由で、プレイ動画についても我輩は否定的だ。結局、ゲームはコンテンツだ。 コンテンツが流出してしまえば、ゲームのマスター価値は著しく低下する。 映画を考えてみよう。「解説しながら映画を流した動画をニコ動にuploadする」 行為が、その映画の売り上げに絶対影響しないか?そんなこたないだろう。
「そういう二次利用が新しい文化を生み出すことがある、だからある程度は
認めて欲しい」と主張する人々がいる。オーケー、二次利用が文化発展に
貢献することがあるのは認めよう。だったら、ちゃんと許諾を取ろうよ。
二次利用したいならちゃんと著作者にその旨を問い合わせようよ。
義務を果たさず権利だけを要求するのは子供のワガママだ。上の主張は、
「文化の発展のためだから、他人の家に押し入って金品を根こそぎ強奪してもいい、
結果その家の人が飢え死にしようが知ったこっちゃない」に等しい。
そうじゃなくて、まずは玄関の呼び鈴を押し、「申し訳ありませんが
少しお金を分けていただけませんか」とお願いする、そういう謙虚な姿勢で臨もう。
※フランスみたいに法律でパロディを規定してればこんな問題はないと思うのだが、
残念ながらニッポンジンはそういうの苦手みたいだ。これは本当に残念だと思う。
ことほど左様に状況が逼迫していることを、本当にマヂで皆様には理解して欲しい。 心から。だからどうしろとは言わない。でも理解はしておいて欲しい。
かような現状を打破するために、本書では、不正コピー防止を目標とし、 まずロジカルシンキンのHOWツリーを使ってその方法を考えてみる。 ざらっと考えて出てきたHOWツリーは以下のとおり。 太字のものは対策として使えそうなもの。 ここでは同人ソフトを対象にしているので、 普通の人ができそうにないこと(ドングルとかメディアに細工とか)は省いているが、 メーカーがプロテクトかけるなら(批判はあるかもしれないが) そのくらいのことは考えてもいいと思う。メディアに細工とかは一般的だしね。
とりあえず思いつくのはこんなものだろうか。
何故不正コピーされてしまうかといえば、こちらもやっぱり簡単にコピーでき、 簡単に頒布可能で、しかもそれを誰もチェックしていないからだ。だったら 簡単、頒布を不可能にするか、不正に頒布されたものかどうかをチェックすればよい。
これらをチェックするには、直接メディアの最内周データを読み込まなければ ならないため、SPTI (SCSI Pass-Through Interface) を使うか、 CreateFile('\\.\ドライブ名:')してReadFile()する必要がある。 Vista以降は書き込み指定 できなくなったようだ(なんでそういうことをしてしまうのかMS)が、 まぁ関係ないだろう。
ただし、ローカルアクティベーションでは、どうしてもIDの正当性をローカルで チェックする必要がある。一つでもIDが流出すればプロテクトの意味が 無くなるし、解析によりIDの規則性が流出すれば、同じ手法が二度と使えなく なってしまうことに注意。
アクティベーション時、「製品の個別IDとユーザのメールアドレスを 登録すると、アクティベーションし、アクティベーション無効化のパスワードを 通知する」ようなシステムになっていれば、ユーザの特定、 製品の個別IDとアクティベーションIDの対応などがメーカー側で 一括管理できるため、不正コピーをかなり防止することができる。ユーザも 任意でアクティベーションを無効化できるので、別のPCにインストールする時や (あんま感心しないが)中古屋へ売る時にも安心。
ただし、この方法では、以下の条件が必要になる。
いまや1.は無視可能と思うが、2.はかなり難しい。 解決策としては、ネットワークアクティベーションの必要性を時限式とし、 発売から一定期間(一年くらい?)が 経過したら、ローカルアクティベーションだけでゲームを遊べるように、 最初からチェックルーチンを作りこんでおくことだ。 同人ソフトにしても商業ゲームにしても、一年を経過して売れ続ける ようなことはまず無いし、そこまで待ってでも(ローカルアクティベーションの ID流出による)コピー品をプレイしたいという人は更に少ない。従って、 このような制限で必要十分。…だと信じたい。
注意点としては、アクティベート済みのイメージがごっそり流出してしまえば、 結局コピー同様となってしまうこと。ユーザのメールアドレスがあればある程度 流出者を特定できるので、抑止力とはなりうるが、捨てメールアドレスなどを 利用されれば完全ではないことに注意。これを防止するには、他の方法と 組み合わせる必要がある。
ネットワークアクティベーション時に、ゲームに必要なファイルをメーカーから ダウンロードさせるようにしておくと、更に安全性が向上する。反面ユーザの 利便性は低下するけどね……。
後述するが、これらのIDをファイル暗号化のキーに使えば、更に強固な暗号化が 可能となる。というか同一マザー上でないとプレイできなくなる。なかなか酷い。
しかし、そのたびにネットに接続していたのでは、ウィルスチェックソフトに 怒られたり、スパイウェアだと罵られたりする可能性がある。マニュアルなどで 先にその旨詳らかにしておくことを忘れずに。また、実際ネット接続できない時は プレイできないと、オンラインゲームと何が違うのかわかんなくなっちゃうことにも 注意が必要。
画像・シナリオ・音楽データの不正頒布を防止するには、 データの暗号化が一番だ(こちらで述べている)。 暗号化は、不正コピー防止の各方法と組み合わせて使うことで、より強固となりうる。
当然ネットワークに接続しないとプレイできないので、ローカルプレイできなくて
困るユーザが出てしまうことに留意すると、
現実的にはこの方法はそのままは使えない。
アクティベーションの時に、必要なファイルをローカルIDでエンコードした後
メーカーからダウンロードさせるようにすれば、
プロテクトの一種として使えなくもない。
そのために必要な、「ある.xp3ファイルだけ別のデコードをするための方法」は
別ドキュメントの下の方ででこっそり紹介済み。
色々考えることはあると思うが、 ここで目指すのは「同人レベルの対策」ということで、まず、 そんなに煩雑ではない「ローカルアクティベーション+α」という方法を考えてみる。 即ち、「完全に違法コピーを防止することはできないが、抑止力にはなりえる」 方法を考えてみる。ユーザに優しく、メーカー・サークルに優しく、実装には そんなに時間やりソースがかからない、そんな方法が理想。
まずは最も単純な「ローカルアクティベーション」のコピープロテクトを考えよう。 以下のような方針で実施する。
簡単だ。ネットワークとか全然使わないし、ユーザもメディア(と ユニークキー)を保存するだけで済む。 ユーザローカルではインストールし放題だし、一度ユニークキーがもれちゃうと 全く何のプロテクトにもならないけれど、まぁ基本ということで。
ユニークキーは、ゲーム側で正当かどうかを確認する必要がある。単純に ユニークキーのリストをゲーム側に持っていると、解析されてあっという間に ユニークキーが全部放流されてしまうので、ここはちょっと捻ろう。 具体的には、「ゲーム側でリストを持っているのは ユニークキーのハッシュ値」にすればよい。 つまり、ゲーム側(ユーザのローカル)では、用意されている全てのユニークキーの ハッシュ値リストを持っておき、与えられたユニークキーのハッシュ値と これを比較することで、正当であるかどうかを判断すればよい。例えば、md5値を ハッシュとするならこんな。
与えられたユニークキー | そのハッシュ値 | ゲーム側で持っているハッシュ値リスト | |
---|---|---|---|
"ccc" | 9df62e693988eb4e1e1444ece0578579 |
47bce5c74f589f4867dbd57e9ca9f808 08f8e0260c64418510cefb2b06eee5cd 9df62e693988eb4e1e1444ece0578579(これが同じ) 77963b7a931377ad4ab5ad6a9cd718aa |
キーからハッシュ値を求めるのは簡単だが、ハッシュ値からキーを求めるのは
極めて難しい(ことになっている)。だから、ハッシュ値をユーザ側でリストして
いても、それとマッチするキーをユーザが推測することは不可能に近い。嘘だと
思うなら、上のハッシュ値リストについて、残りの三つの元キーをひねり出そうと
してみるといい。ほーら、難しいでしょ?正解は、それぞれ"aaa"、"bbb"、"ddd"
でしたとさ。
従って、このように、ユーザ側にユニークキーのハッシュ値リストを持って
いたとしても、ユニークキーそのものが大量に漏出することはまずない。反面、別の
ユニークキーのハッシュ値がどれかと重なる可能性(衝突という)もあるにはあるが、
母数が10000だとしても、md5が重なる可能性は極めて低いので、それは無視可能だ。
とはいえ、最近md5は衝突する値を探し出すのが現実的な時間で
可能になったという話を聞く。カンペキではないということだ。代わりにsha512
とかにしてもいいが、そうすると今度はチェックのためのハッシュ値リストが
巨大になったりする(512bit=64byteなので、10000キー用意すると640KBになる)ので、
どっかで見切りをつけて割り切る必要がある。
…というようなのを実装するには、以下のようなファイルが必要となる。 ユーザ側(ゲーム側)に配置するのはaaaaaaaa.tpmとaaaaaaaa.datの二つのみで、 これらをゲームのplugin/ディレクトリ以下に置いて、ゲームスクリプトから TJS関数を呼び出し、戻り値を判断する。
以下のファイルを元に、ローカルアクティベーションの実現方法を示す。
これにより、ゲーム起動後、checkUniqKey() が実行される度に、 ユニークキーの存在がチェックされ、必要であればダイアログボックスを開いて ユニークキーを確認するようになる。
機能 | ファイル | ソースコード | 説明 | |
---|---|---|---|---|
キーチェックdll | aaaaaaaa.tpm | ● |
ゲームのplugin/ディレクトリ以下になんとか.tpmという名前で配置。 これは、TJSの関数 checkUniqKey(hashlistfile, uniqkeyfile) を定義する吉里吉里 プラグインだ。関数詳細は以下の通り。
| |
ハッシュ値リスト | aaaaaaaa.dat | - |
上の checkUniqKey() に指定するfileの実体。だから、ファイル名と配置位置は
適宜変更すること。ヘンな名前にすれば、クラッカーを欺ける可能性あり
(拡張子を.dllにしたりしてるのはそのため)。
中身はユニークキーのハッシュ値リスト(バイナリ)。上のaaaaaaaa.tpmが読み込み、
ユニークキーが正しいかどうかチェックするために利用する。
これはテスト用のものであり、以下の五つのユニークキーに対するハッシュ値が 格納されている。従って、このデータを使うと、以下五つのユニークキーのみを 受け付ける。
ユニークキーをばらしちゃってるので、 この頒布されているハッシュ値リストファイルを、 テスト目的以外では使わないこと。 実際には、次のプログラムmakehashdata1.plから自動生成されるものを使えばよい。 |
|
ユニークキー・ハッシュ値リスト生成スクリプト | makehashdata1.pl | - |
以下のように実行することで、
上のハッシュ値リストファイルを(500人分)自動生成することができる。
cygwin上でも実行できるし、ヘンなライブラリとか使ってないから、perlが動けば
フツーにどこででも使えるんじゃなかろうか。 ※500などの数値はそのゲームで見込まれるユーザ数のmaxを 必ず越える値にすること!今の仕組みだと途中で追加できないし、生成する度に ユニークキーは全く別のものになるから、一度組み込んじゃうと変更できないため 。
ユニークキーのリスト(500個分)はゲーム名.txt中に記録され、それに対応する
ハッシュ値リストが「ハッシュ値リストファイル」に格納される。
ゲーム名.txt 中のユニークキーを個々に印刷して、頒布媒体一枚一枚に添付すれば
よい。スゲータイヘンだけど。 |
どうだろう。案外簡単に実装はできることがわかっただろうか。 まだまだ捻らないとプロテクトとは言えないが、 最も基本的な考え方はこんなカンジだ。 KAG/TJS上でプロテクトをかけることの是非を問う声もあるが、我輩は、柔軟性も 考えてそれでもいいと思う。 別頁で述べているXP3ファイルの暗号化を併用することで、 書き換えられる可能性も低くなるし。
次のコピープロテクトは、もう少しハードルの高いネットワークアクティベーションを
考えてみる。ユーザのメールアドレスも一緒に登録させることで、
「誰が」ユニークキーを保持しているかを「メーカー側で把握」し、
再登録や無制限のコピーを(倫理的に)防ぐというカンジだ。
ユーザにまぁ優しく、メーカー側の負担も小さく、
コピーへのハードルはちょっと高い、
(同人ゲーム向けであれば)バランス取れた方法だと思う。
できるメーカーなら、2.と3.は「ゲーム起動したら自動的にユーザに問い合わせ、 メーカーに情報を送り、メーカーからのユニークキー2を自動的に記録する」 ように作れば、ユーザの負担は極めて少なくなるだろうが、まぁそこまでしなくても いいだろう(それだとメールアドレスの有効性確認もイマイチだし)。
これらにより、同じユニークキー1と別のメールアドレスの組が
申請されたら、「こいつコピーしてるー!」というカンジのことが判断可能になるし、
正当でないユニークキー1が何度も入力されるならクラックされてる可能性を
判断できる。加えて、メールアドレスをメーカーに晒すことは、違法コピーの
抑止力となりうる。たとえ捨てアドレスだったとしても、履歴が残る以上足が完全に
消えるわけではないので、抑止力としての効果は高い(と信じたい)。
反面、メーカー側にはこのメールアドレスを漏洩しないための仕組みが必要に
なるのであるが。
登録済みのユニークキー2が漏洩した場合、ユーザサイドでの無制限のコピーを 防ぐ手段はないが、メーカー側にはユーザのメールアドレスがあるわけで、 どのユーザがユニークキー2を漏洩したかが確認可能。これも抑止力としての 効果を期待する。
以下のファイルを元に、ネットワークアクティベーションの実現方法を示す。
これにより、ゲーム起動後、checkUniqKey() が実行される度に、 ユニークキー2の存在がチェックされ、必要であればダイアログボックスを開いて ユニークキー2を確認するようになる。ユニークキー2は、メーカーのCGIページに アクセスして、ユニークキー1とユーザのメールアドレスを入力することで メーカーからメールで送られてくる。
機能 | ファイル | ソースコード | 説明 | |
---|---|---|---|---|
キーチェックdll | aaaaaaaa.tpm | ● | 方針1のものと全く同じ。ユニークキー2を入力するとゲームができるようになる。 | |
ハッシュ値リスト | aaaaaaaa.dat | - | これも方針1のものと全く同じ。確認するのがユニークキー2に変わっただけ。 次のプログラムmakehashdata2.plで自動生成されるものを使うこと。 | |
ユニークキー・ハッシュ値リスト生成スクリプト | makehashdata2.pl | - |
以下のように実行することで、上のハッシュ値リストファイルと、
ユーザデータリストcsv(の初期値)を500個分自動生成する。 ※500などの数値はそのゲームで見込まれるユーザ数のmaxを 必ず越える値にすること!今の仕組みだと途中で追加できないし、生成する度に ユニークキーは全く別のものになるため、一度組み込んじゃうとやり直しは 効かないため。
ユニークキー1、2のリスト(500個分)は、「ゲーム名.txt」中に記録され、 それに対応するハッシュ値リストを持つ「ハッシュ値リストファイル」を作成する。 「ゲーム名.txt」中のユニークキー1を個々に印刷して、 頒布媒体一枚一枚に添付すること。生成された「ゲーム名.csv」は、 ユーザ情報を扱うデータとしてメーカーのアクティベーションページで使用する。 当然、「ゲーム名.txt」及び「ゲーム名.csv」はメーカー側だけに 保存すること。 |
|
アクティベーションCGI | ゲーム名.cgi | - |
https(httpじゃダメよ!)サーバ上に配置。
ユニークキー1とメールアドレスを受け取り、
それらが正当であればユニークキー2を記したメールを返す。やることは以下の通り。
これらは全て、メーカーのhttpsサーバ上で実行する。
一応、ユーザのメールアドレスは、ゲーム名.csv が漏洩してしまった時のことを考えて、生テキストでは持たない ようにbase64エンコードしている(ここでバラしたら意味ないけど)。md5hashに しちゃうと、元のメールアドレスがわかんなくなっちゃうので、可逆なエンコード 方法を使わないとダメなのが歯がゆい。 以下のパラメータがデフォルトで設定されている。環境に合わせて適当に変更すること。 例えば /var/lib/gamename/gamename.csv や /var/log/gamename.log、 /var/lock/gamename.lck は、 CGIの実行者(Linuxならapache.apache)の権限で上書きできないといけないので注意。
|
これらのプロテクトは、「ユーザサイドのデータを、クラッカーが書き換えることが できないこと」によってのみその威力を発揮する。ユーザサイドでデータが 書きかえられちゃうと、もう全く意味がなく、プロテクトなんかさくさくと 解除されてしまう。というわけで、 吉里吉里/KAGでのデータ暗号化(実践編)で頒布しているような、改竄防止の 仕組みも必ず併用すること。「こうすればプロテクト回避できるのがわかってるのに 書き換えられないー!」という葛藤を、ライトクラッカーに味合わせることができて ちょっとスッキリ、かもしれない。
本当は、暗号化と不正コピー防止プロテクトは複雑に絡めた方がいいんだけど、 ここでは説明のための単純化のため、分離して説明している。
というわけで、とっても簡単で効果もそこそこなコピープロテクトの手法を一つ 紹介した。ホンモノのクラッカーからすればこんなものは子供だましで、(ついでに 方法も具体的に示しているから、)ハナクソほじりながら回避されちゃうのであるが、 少なくともライトユーザのライトコピーくらいは防げるよな、ということで一つ。