JavaScriptの難読化をする目的は主に3つ
- コードを解読されにくくしたい
- コメントとかも全消去したい
- 少しでもコードサイズを減らしたい
そこでよさげなツールがないか探したところ・・・
オンラインでできる Obfuscator というツールを発見!
オンラインで難読化できて超便利でした。
この Obfuscator について色々まとめとこうと思います。
ツールの使い方自体はとても簡単。難読化が捗る
では早速 Obfuscator の使い方について。
まずツールページはコチラ
▼ JavaScript Obfuscator Tool
▼ コード難読化の画面
超簡単なコードを難読化してみます。
▼ 超適当に作ったコード
1 2 3 |
var x = 42; console.log('x : ', x); /// => x : 42 |
コード貼り付けしたら【Obfuscate】をクリック
▼ 実際に生成された難読化コードがコチラ
1 |
var _0xd2bb=['log','x\x20:\x20'];(function(_0x3c7543,_0x28a4a4){var _0x1a43bd=function(_0x2a6c5c){while(--_0x2a6c5c){_0x3c7543['push'](_0x3c7543['shift']());}};_0x1a43bd(++_0x28a4a4);}(_0xd2bb,0x7d));var _0x2530=function(_0x3c7543,_0x28a4a4){_0x3c7543=_0x3c7543-0x0;var _0x1a43bd=_0xd2bb[_0x3c7543];return _0x1a43bd;};var x=0x2a;console[_0x2530('0x1')](_0x2530('0x0'),x); |
・・・・・・??
これはすごい(語彙力)
あんな単純なのが、ここまで複雑になるとは驚きです。
- プロパティ・関数を配列とかで冗長化
- 処理の複雑化(上コードの _0x2530 など)
- 数値を16進数表記に変換( x=0x2a など)
これは単純なコードなので、まだ解読できます。
そこでもっと複雑なコードを書いてみました。
▼ オブジェクトとか関数を含むコード例
1 2 3 4 5 6 7 8 9 10 11 |
var fruits = { 'a': 'Apple', 'b': 'Banana', 'c': 'Cherry' }; function getFruit(key){ return fruits[key] || 'None'; } console.log(getFruit('a')); console.log(getFruit('b')); console.log(getFruit('c')); |
▼ 実際にobfuscatorで生成された難読化コード
1 |
var _0x5aa2=['Apple','log','Cherry','None'];(function(_0x5f4fe4,_0x5aa284){var _0x445485=function(_0x322c9d){while(--_0x322c9d){_0x5f4fe4['push'](_0x5f4fe4['shift']());}};_0x445485(++_0x5aa284);}(_0x5aa2,0x1f4));var _0x4454=function(_0x5f4fe4,_0x5aa284){_0x5f4fe4=_0x5f4fe4-0x0;var _0x445485=_0x5aa2[_0x5f4fe4];return _0x445485;};var fruits={'a':_0x4454('0x0'),'b':'Banana','c':_0x4454('0x2')};function getFruit(_0x379ab5){return fruits[_0x379ab5]||_0x4454('0x3');}console[_0x4454('0x1')](getFruit('a'));console[_0x4454('0x1')](getFruit('b'));console[_0x4454('0x1')](getFruit('c')); |
もはや何の処理をしてるかさえ推定が難しい。
ただマジックナンバー、定数、関数名は完全に隠れない模様。
でも数百行を超えるコードなら 効果ありそうですね。
試しに難読化コードの解除を試みてみた
とはいえ、難読化しても全く安心ではありません。
世の中には 難読化の解除ツール もあります。
そこで今 Obfuscator で難読化したコード
これがどの程度 コード解除 に耐えられるか、検証してみました。
ここで使う解除ツールはコレ
▼ Online JavaScript Beautifier
オンラインで手軽に試せるツールです。
そして今回検証に使ったのは次のコード
▼ こちらのコード
1 2 3 4 5 6 7 8 9 10 |
class Sweet{ constructor(name){ this.name = name; } } var donut = new Sweet('Donut'); var eclair = new Sweet('Eclair'); var lollipop = new Sweet('Lollipop'); var nougat = new Sweet('Nougat'); |
なんの実用性もないけどサンプルということで、、、
あと class みたいにES2015以降の構文でも難読化OKです。
▼ 上コードが難読化された結果
1 |
var _0x527e=['Lollipop','Donut','Nougat','name','Eclair'];(function(_0x13ca8e,_0x527e27){var _0x4f24c7=function(_0x25851b){while(--_0x25851b){_0x13ca8e['push'](_0x13ca8e['shift']());}};_0x4f24c7(++_0x527e27);}(_0x527e,0xb7));var _0x4f24=function(_0x13ca8e,_0x527e27){_0x13ca8e=_0x13ca8e-0x0;var _0x4f24c7=_0x527e[_0x13ca8e];return _0x4f24c7;};class Sweet{constructor(_0xcd32ce){this[_0x4f24('0x0')]=_0xcd32ce;}}var donut=new Sweet(_0x4f24('0x3'));var eclair=new Sweet(_0x4f24('0x1'));var lollipop=new Sweet(_0x4f24('0x2'));var nougat=new Sweet(_0x4f24('0x4')); |
やはり変数名とかは元のまま。
またクラス名とかも当然ながら隠ぺいなどはされません。
そして難読化解除した後の結果がコチラ!
▼ こんな風なコードになった
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
(function(_0x13ca8e, _0x527e27) { var _0x4f24c7 = function(_0x25851b) { while (--_0x25851b) { _0x13ca8e['push'](_0x13ca8e['shift']()); } }; _0x4f24c7(++_0x527e27); }(_0x527e, 0xb7)); var _0x4f24 = function(_0x13ca8e, _0x527e27) { _0x13ca8e = _0x13ca8e - 0x0; var _0x4f24c7 = _0x527e[_0x13ca8e]; return _0x4f24c7; }; class Sweet { constructor(_0xcd32ce) { this[_0x4f24('0x0')] = _0xcd32ce; } } var donut = new Sweet(_0x4f24('0x3')); var eclair = new Sweet(_0x4f24('0x1')); var lollipop = new Sweet(_0x4f24('0x2')); var nougat = new Sweet(_0x4f24('0x4')); |
う~~~ん、この例だと難読化した意味をあまり感じない。
でも素の文字列などは難読化されたままですね、
そこで手元にある1000行くらいのコードで試してみると、、、
- 変数名・関数名などほぼ記号化
- 何が書いてあるかも全く分からない
- コードサイズも気持ち若干減る
こういう結果に。
結論としては、実用レベルなら申し分ないですね。
ここまでのまとめ - 難読化はオンラインで十分
ということで以上がJavaScriptの難読化の効果。
ただし難読化でコードがばれない、という訳ではないので注意!
そもそも見られて困るコードはサーバー側に置きましょう。
以上、JS難読化ツール Obfucator についてでした。ではまた