DxLib Advent Calendar 2018
この記事はDxLib Advent Calendar 2018 9日目の記事です
過疎っている。
はじめに
はいはい、タイトル長い長い。もともと2分割しようと思ってた内容を諸事情で一つにくっつけたからこうなる。
DxArchiveとは
正直必要性がわからない機能。
zipファイルと同じアルゴリズムで圧縮が一応かかるとはいえ、ゲームの素材なんてものはもともと圧縮されているものだからむしろ容量が増えるまである。
誰得なんだ・・・?
https://dxlib.xsrv.jp/cgi/patiobbs/patio.cgi?mode=view&no=4534
名前:管理人 日時:2019/12/03 00:09
プログラム初心者の方が作成するソフトの多くが画像や音やテキストファイルが生のままDataフォルダに入っていて、
見ようと思えばゲームをクリアすることなくエンディングの画像やストーリーが見れてしまうのをなんとかしたい
・・・普通にデコードできるのでは・・・?
友人「ゲーム配布するときに素材フォルダをいじられて起動しなくなると困るので固めるために使う」
・・・なるほど、わからん。それDXAファイルを動かされたらあっさり詰むやつでは・・・?
やっぱり不要では?
DxArchiveの暗号化機能
そんな必要性が謎なDxArchiveに更に謎な機能として暗号化機能がある。
・・・何に使うんだ?
8127氏
ライセンスを購入して使用する有料ゲーム素材の中には(無断二次利用防止のため)
暗号化必須で使ってくださいというものがあるので、暗号化機能が無くなったりするととても困ります。
やっぱり謎。そもそも復号化するための鍵がクライアントサイドに最終的に有るのだから、どんなに頑張っても原理的に復号できる。
いや、もちろん復号するコストは上げられる。しかしDRMが滅びつつあるように、コンテンツ保護機能というものは基本的に害悪なのだ。
そして大抵のオチはコンテンツ保護機能がバグってクラッシュするとか、サーバーが閉鎖されて鍵が手に入れられなくなるとかそういうクソみたいな結末だ。
手元にFairUse4WM
(有名なDRM解除ソフト)で解除できねーぜって謳って、破れるもんなら破ってみろと配布されていたDRM付きWMVがあるが、サーバーが閉鎖されて正規の再生もできなくなった。
じつにばかばかしい行為なのである。
しかしながら、無知な素材作成者が無意味にも暗号化を要求してくる以上そうせざるをえないのだろう。現実ってそんなもんらしい。
2018/08/12まで存在したDxArchiveの暗号化機能の脆弱性とそれに伴う仕様変更
にて報告された。
なんと共通鍵を持っていなくても、また共通鍵を求めることなく復号化できるという致命的なバグがあったのだ。
・・・暗号化 #とは
というわけで、議論の末Hash関数にSHA-256を採用しつつ暗号化するように変更がなされました。12byteから一気に増えたね。
Export Administration Regulations 輸出管理規則(ESR)
アメリカには実に滑稽な法律がって、Export Administration Regulationsというやつがそれなのだが、要するに暗号化技術の一部に対して規制がかかりますよ、というものだ。
昔は今以上に規制が厳しくて、たとえばPGPはアメリカ国外へソースコードを含むソフトウェアを輸出できないというお馬鹿な事態が発生していた。
仕方ないからThe PGPi scanning project
っていうのが立ち上がって、紙媒体なら法律で規制外という点を突いてソースコードを印刷して本12冊に分冊して出版、ヨーロッパの有志によってOCRされリリースとかいう茶番が繰り広げられていた。
暗号化ソフトのソースコードを6000ページもの本12冊にして合法的に輸出した壮大なプロジェクト「PGPi scanning project」 - GIGAZINE
で、この規制が若干緩んだものの今もなお存在してる。
ところで執筆現在でもよくわかっていないんだが、このESRってワッセナー・アレンジメントに含まれているんですか?外為法第25条を眺めてもよくわからんかったんですが。
追記:
たまたまTwitterで @arclisp 氏が
— シミュラクラ (@arclisp) 2018年12月24日
共通鍵暗号方式(対象鍵と言及されている)のは56ビット長以上だと外為法に抵触するので経産省に事前届出がないと輸出はアウトっぽいような文面ではある
— シミュラクラ (@arclisp) 2018年12月24日
輸出令別表第1の9の項(7)(省令第8条第九号)情報セキュリティ(暗号装置)該非用パラメータシート(情報セキュリティ・貨物) 様式9-07
http://www.cistec.or.jp/publication/teisei_data/b-03tuushin/20180130.pdf
というのを見つけました。
追記:
上記はリンク切れになったようです。
http://www.cistec.or.jp/publication/shoseki/sample/b03-tuushin_kinyurei.pdf
の41ページ目に
CISTEC 2019.1.9 平成31年1月9日施行政省令等対応
の文字が見えます。これは見本なので見本じゃないやつがあるはずです。
おそらく
http://www.cistec.or.jp/koumoku/para/parameter.html
から落とせるのだと思うのですが、どういうわけか認証が要求されてしまい、見れません。
CISTEC 2018.1.22 平成30年1月22日施行政省令等対応
https://www.jmcti.org/publication/correction/pdf/2017/20180130.pdf
これなら見つかりました。
DxLibへの影響
で、これがDxLibに影響あるんじゃないかという指摘が10/31になされました。
さて、ESRですが、Export
というぐらいだから、アメリカからの輸出に対しての規制です。
これだとピンときてないかもしれないのでもうちょっと踏み込むと、AndroidのGoogle PlayとかApple StoreとかGithub ReleaseとかNugetとかはアメリカ国内に拠点を持つ企業のサービスであり、アメリカからの輸出に該当します。
DxLibには以前は12byte=96bitの鍵、上述の通りSHA-256すなわち256bitへの変更があり、いずれにせよ共通鍵方式で56bitを超える鍵が利用されてきました。
- DSAS開発者の部屋:スマホアプリと米国輸出規制に関するメモ
- DSAS開発者の部屋:スマホアプリと米国輸出規制に関するメモの続き
- HTTPS を使ってるアプリを AppStore や Android Market で配信するときの輸出手続きについて - むらかみの雑記帳
- HTTPS を使ってるアプリを AppStore や Android Market で配信するときの輸出手続きについて(その2) - 規制対象になるかどうかの判断 - むらかみの雑記帳
- HTTPS を使ってるアプリを AppStore や Android Market で配信するときの輸出手続きについて(その3) - 暗号分類 - むらかみの雑記帳
- HTTPS を使ってるアプリを AppStore や Android Market で配信するときの輸出手続きについて(その4) - 商務省BISに暗号登録してみたよ! - むらかみの雑記帳
というわけでこの辺をみつつ、影響を解釈していきましょう。
DxLib自体
これはDxLibの再頒布も含みます。
結論から言うと届け出(許可例外TSU)が必要です。
何故かと言うとDxLibはNuGetでも配布されており、共通鍵方式で56bitを超える鍵が使われているからです。
というわけでDxLib自体は届け出(メールを投げつける)をやったそうです。
ところが、DxLibは結構あちこちで再頒布されているらしく、ここで問題が生じます。
つまりアメリカからの輸出という形態に該当する形で再頒布するたびに再頒布を行う主体の人が届け出(許可例外TSU)をしなければならないということです。
**業を煮やしたDxLib作者は鍵を56bitに弱体化すると表明しました。**まじかよ・・・。
結局CRC32を2回適用して56bit分取り出し、LZ圧縮とハフマン圧縮で固定ヘッダー攻撃防止を行ったようです。
DxLibのDXA暗号化機能を利用していないアプリケーション
届け出不要です。
DxLibのDXA暗号化機能を「知的所有権・著作権保護」のために利用するアプリケーション
届け出不要です。
DxLibのDXA暗号化機能をその他の目的で利用する場合
一体どんなことをすればこれに該当するのかわかりませんが、例えば通信の暗号化にDXAの暗号化を使ったとかそんなんですかね・・・?
この場合はECCN番号分類に従って手続きが必要になります。
結論
自由ソフトウェアの発展を阻害するExport Administration Regulationsは死すべし、慈悲はない。
余談: DxArchiveの暗号化機能を利用するときにパスワードをどのようにプログラム内で指定するべきか
まあ何やっても完全に秘匿することはできないわけですが、そのまま文字列リテラルとして書いてしまうとバイナリエディタで実行ファイルを覗くだけでパスワードがわかってしまいます。
せっかく暗号化機能を使うなら流石にもうひと工夫くらいしたほうがいいでしょう。
#include "inferior_encrypted_string.hpp"
#include <iostream>
#if defined(DXLIB_CUSTOM_NO_CXX11_CONSTEXPR) && defined(DXLIB_CUSTOM_NO_CXX14_CONSTEXPR)
const inferior_encrypted_string::inferior_encrypted_string<char, sizeof("arikitari")> s1 = inferior_encrypted_string::make_inferior_encrypted_string("arikitari");
const inferior_encrypted_string::inferior_encrypted_string<char, sizeof("ありきたりな世界")> s2 = inferior_encrypted_string::make_inferior_encrypted_string("ありきたりな世界");
#else
constexpr auto s1 = inferior_encrypted_string::make_inferior_encrypted_string("arikitari");
constexpr auto s2 = inferior_encrypted_string::make_inferior_encrypted_string("ありきたりな世界");
#endif
int main()
{
std::cout
<< s1.str << std::endl
<< s1.decrypt() << std::endl
<< std::endl
<< s2.str << std::endl
<< s2.decrypt() << std::endl;
}
のようにすることでDxLibが対応するコンパイラすべてでコンパイルは通りつつ、C++11のconstexprが利用できればバイナリエディタからは覗けなくなります(C++11consteexprが利用できない環境では無意味です)。
中身的には各byteに31を減算する作業をコンパイル時に行って、実行時に31を加算して戻しているだけのものです。
なお
add BYTE PTR [ecx],0x1f
のようなかなり特徴的なコードが吐かれるようなので依然として破るのは簡単だったりします。