Electronと秘匿化・難読化・整合性チェック

このエントリは[Electron Advent Calendar 2016 - Qiita](http://qiita.com/advent-calendar/2016/electron)の6日目です。

### はじめに
Electronでアプリケーションを作成する場合、コードを見せたくないといったことがあると思います。
そこで、どのようなアプローチがあるのか調べてみました。
(間違っている点、足りない点はフォローいただけると助かります。)

### 秘匿化
Electronのissueでは下記で話題に挙がっています。

* [Source Code Protection](https://github.com/electron/electron/issues/3041)
* [Is the source really protected with building apps with Electron?](https://github.com/electron/electron/issues/2570)

なんとなくまとめると、

* Electron公式ではソースコードの秘匿化をする機能はない。  
今のところやるつもりもない。  
(提供されている`asar`はパフォーマンス向上のためのツール)
* ソースコードの秘匿化がしたいなら、[NW.js](https://nwjs.io/)に移行したほうがいいかも。
* [EncloseJS](http://enclosejs.com/)も同じことが出来るけど、商用ソフトに使う場合は料金が発生する。

### 難読化
次に難読化を考えてみます。
ここから先は、Electronというよりは、JavaScriptコードの難読化の話となります。

[electron-vue](https://github.com/SimulatedGREG/electron-vue)を題材に難読化を試していきます。

#### webpack
まずは`webpack`から。
基本の`uglify`を行います。

```javascript:webpack.config.babel.js
const webpack = require('webpack')

let config = {
  entry: {
    build: path.join(__dirname, 'app/src/main.js')
  }
}

if (process.env.NODE_ENV === 'production') {
  config.plugins.push(
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"'
    }),
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  )
}
```
これでビルドをすると、
![Screen Shot 2016-12-05 at 02.30.05.png](https://qiita-image-store.s3.amazonaws.com/0/98379/b99c6312-c450-a5c9-1847-e11417ddf185.png "Screen Shot 2016-12-05 at 02.30.05.png")
こんな感じのファイルが出力され、アプリも問題なく起動します。

![Screen Shot 2016-12-05 at 02.21.39.png](https://qiita-image-store.s3.amazonaws.com/0/98379/74e28a62-eb14-cac4-96d1-37360452aee2.png "Screen Shot 2016-12-05 at 02.21.39.png")

#### webpack-obfuscator
まだまだ心許ないので、もう少し難読化をしてみましょう。
`webpack`プラグインの`webpack-obfuscator`を使用します。

```javascript:webpack.config.babel.js
const webpack = require('webpack')
const WebpackObfuscator = require('webpack-obfuscator')

let config = {
  entry: {
    build: path.join(__dirname, 'app/src/main.js')
  }
}

if (process.env.NODE_ENV === 'production') {
  config.plugins.push(
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': '"production"'
    }),
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),
    new WebpackObfuscator ({
      rotateUnicodeArray: true,
    })
  )
}
```
これでビルドをすると、
![Screen Shot 2016-12-05 at 02.38.08.png](https://qiita-image-store.s3.amazonaws.com/0/98379/461d9d45-1a36-2b1d-003d-8e902608949b.png "Screen Shot 2016-12-05 at 02.38.08.png")

こんな感じのファイルが出力され、アプリもこれまた問題なく起動します:blush:  

![Screen Shot 2016-12-05 at 02.37.50.png](https://qiita-image-store.s3.amazonaws.com/0/98379/1d471be5-ffc5-8895-6a7b-8b70da4e77dc.png "Screen Shot 2016-12-05 at 02.37.50.png")

今回はベンダーJSもまとめて難読化しちゃってますが、
ビルド・実行速度の観点からもベンダーJSはエントリーを分けて、
アプリケーションJSのみ難読化することをオススメします。

```javascript:webpack.config.babel.js
new WebpackObfuscator ({
  rotateUnicodeArray: true,
}, ['vendor.js'])
```

こんな感じで`vendor.js`のみ`webpack-obfuscator`の難読化対象から外すことができます。

詳細なドキュメントは、

* [webpack-obfuscator](https://github.com/javascript-obfuscator/webpack-obfuscator)
* [javascript-obfuscator](https://github.com/javascript-obfuscator/javascript-obfuscator)

あたりを参照してください。

[Gulp版](https://github.com/javascript-obfuscator/gulp-javascript-obfuscator)もあるみたいなので、Gulpを使ってる人はそちらをお試しください。

### 整合性チェック
MacOS限定ですが、`electron-builder`の作者によって、こんな[PR](https://github.com/electron/electron/pull/9648)が出てました。
まだマージはされていません。[^1]


[^1]: 2017/08/17 現在