DxLibのDxArchiveの暗号化する機能とExport Administration Regulations 輸出管理規則

## DxLib Advent Calendar 2018

この記事はDxLib Advent Calendar 2018 9日目の記事です

[<< 8日目|自作のノベルゲームエンジンを作ってみた](https://qiita.com/S_H_/items/a983c1ade26f57ce942e) || [10日目|DXLibで川瀬式MGFを実装 >>](https://qiita.com/nicolai_twi/items/b47ca5df5810b6c85d40)

過疎っている。

## はじめに

はいはい、タイトル長い長い。もともと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の暗号化機能の脆弱性とそれに伴う仕様変更

http://dxlib.o.oo7.jp/cgi/patiobbs/patio.cgi?mode=view&no=4474

にて報告された。

なんと**共通鍵を持っていなくても**、また共通鍵を求めることなく**復号化できる**という致命的なバグがあったのだ。

・・・暗号化 #とは

というわけで、議論の末Hash関数に**SHA-256を採用**しつつ暗号化するように変更がなされました。12byteから一気に増えたね。

## Export Administration Regulations 輸出管理規則(ESR)

アメリカには実に滑稽な法律がって、Export Administration Regulationsというやつがそれなのだが、要するに暗号化技術の一部に対して規制がかかりますよ、というものだ。

昔は今以上に規制が厳しくて、たとえばPGPはアメリカ国外へソースコードを含むソフトウェアを輸出できないというお馬鹿な事態が発生していた。  
仕方ないから`The PGPi scanning project`っていうのが立ち上がって、紙媒体なら法律で規制外という点を突いてソースコードを印刷して本12冊に分冊して出版、ヨーロッパの有志によってOCRされリリースとかいう茶番が繰り広げられていた。

[暗号化ソフトのソースコードを6000ページもの本12冊にして合法的に輸出した壮大なプロジェクト「PGPi scanning project」 - GIGAZINE](https://gigazine.net/news/20130612-pgpi-scanning-project/)

で、この規制が若干緩んだものの今もなお存在してる。

ところで執筆現在でもよくわかっていないんだが、このESRってワッセナー・アレンジメントに含まれているんですか？外為法第25条を眺めてもよくわからんかったんですが。

追記:
たまたまTwitterで [@arclisp](https://twitter.com/arclisp) 氏が

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">うーん <a href="https://t.co/bUgReFvSg5">https://t.co/bUgReFvSg5</a></p>&mdash; シミュラクラ (@arclisp) <a href="https://twitter.com/arclisp/status/1077253827689013250?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">共通鍵暗号方式（対象鍵と言及されている）のは56ビット長以上だと外為法に抵触するので経産省に事前届出がないと輸出はアウトっぽいような文面ではある</p>&mdash; シミュラクラ (@arclisp) <a href="https://twitter.com/arclisp/status/1077254096699088902?ref_src=twsrc%5Etfw">2018年12月24日</a></blockquote>

輸出令別表第１の９の項(７)(省令第８条第九号)情報セキュリティ（暗号装置）該非用パラメータシート(情報ｾｷｭﾘﾃｨ・貨物) 様式９－０７
~~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になされました。

http://dxlib.o.oo7.jp/cgi/patiobbs/patio.cgi?mode=view&no=4534&p=1

さて、ESRですが、`Export`というぐらいだから、**アメリカからの輸出**に対しての規制です。

これだとピンときてないかもしれないのでもうちょっと踏み込むと、Androidの**Google Play**とか**Apple Store**とか**Github Release**とか**Nuget**とかはアメリカ国内に拠点を持つ企業のサービスであり、**アメリカからの輸出**に該当します。

DxLibには以前は12byte=96bitの鍵、上述の通りSHA-256すなわち256bitへの変更があり、いずれにせよ**共通鍵方式で56bitを超える鍵**が利用されてきました。

- [DSAS開発者の部屋:スマホアプリと米国輸出規制に関するメモ](http://dsas.blog.klab.org/archives/52146838.html)
- [DSAS開発者の部屋:スマホアプリと米国輸出規制に関するメモの続き](http://dsas.blog.klab.org/archives/52148551.html)
- [HTTPS を使ってるアプリを AppStore や Android Market で配信するときの輸出手続きについて - むらかみの雑記帳](http://tmurakam.hatenablog.com/entry/20111009/1318137457)
- [HTTPS を使ってるアプリを AppStore や Android Market で配信するときの輸出手続きについて（その2) - 規制対象になるかどうかの判断 - むらかみの雑記帳](http://tmurakam.hatenablog.com/entry/20111010/1318173222)
- [HTTPS を使ってるアプリを AppStore や Android Market で配信するときの輸出手続きについて（その3) - 暗号分類 - むらかみの雑記帳](http://tmurakam.hatenablog.com/entry/20111010/1318185080)
- [HTTPS を使ってるアプリを AppStore や Android Market で配信するときの輸出手続きについて（その4) - 商務省BISに暗号登録してみたよ！ - むらかみの雑記帳](http://tmurakam.hatenablog.com/entry/20111011/1318328575)

というわけでこの辺をみつつ、影響を解釈していきましょう。

### 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の暗号化機能を利用するときにパスワードをどのようにプログラム内で指定するべきか

まあ何やっても完全に秘匿することはできないわけですが、そのまま文字列リテラルとして書いてしまうとバイナリエディタで実行ファイルを覗くだけでパスワードがわかってしまいます。

せっかく暗号化機能を使うなら流石にもうひと工夫くらいしたほうがいいでしょう。

https://gist.github.com/yumetodo/238c52d4382db93e1978743cf299ba4d

```cpp
#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;
}
```

https://wandbox.org/permlink/SOsUuAvhLRbFeWUS

のようにすることでDxLibが対応するコンパイラすべてでコンパイルは通りつつ、C++11のconstexprが利用できればバイナリエディタからは覗けなくなります(C++11consteexprが利用できない環境では無意味です)。

中身的には各byteに31を減算する作業をコンパイル時に行って、実行時に31を加算して戻しているだけのものです。

なお

```asm
add BYTE PTR [ecx],0x1f
```

のようなかなり特徴的なコードが吐かれるようなので依然として破るのは簡単だったりします。

# License

[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.ja)

<a href="https://commons.wikimedia.org/wiki/File:CC-BY_icon.svg#/media/File:CC-BY_icon.svg"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/16/CC-BY_icon.svg/1200px-CC-BY_icon.svg.png" alt="CC-BY icon.svg" width="88px"></a>