Q:.classファイルを暗号化し、カスタムクラスローダーを使用してオンザフライでロードおよび復号化すると、逆コンパイルが防止されますか?
A:Javaバイトコードの逆コンパイルを防ぐ問題は、言語自体とほとんど同じです。市場で利用できるさまざまな難読化ツールにもかかわらず、初心者のJavaプログラマーは、知的財産を保護するための新しく賢い方法を考え続けています。このJava Q&Aの記事では、ディスカッションフォーラムで頻繁に再ハッシュ化されたアイデアに関するいくつかの神話を払拭します。
Java .classファイルを元のJavaソースに非常に似たJavaソースに再構築するのが非常に簡単であることは、Javaバイトコードの設計目標とトレードオフに大きく関係しています。とりわけ、Javaバイトコードは、バイトコードインタープリターとJIT(ジャストインタイム)/ HotSpot動的コンパイラーによって、コンパクトさ、プラットフォーム非依存性、ネットワークモビリティ、および分析の容易さのために設計されました。間違いなく、コンパイルされた.classファイルはプログラマの意図を表現しているため、元のソースコードよりも簡単に分析できます。
少なくとも逆コンパイルをより困難にするために、逆コンパイルを完全に防止しないために、いくつかのことができます。たとえば、コンパイル後の手順として、.classデータをマッサージして、バイトコードを逆コンパイル時に読みにくくするか、有効なJavaコードに逆コンパイルすることを困難にすることができます(またはその両方)。前者には極端なメソッド名のオーバーロードを実行したり、制御フローを操作してJava構文では表現できない制御構造を作成したりする手法は、後者にはうまく機能します。より成功した商用の難読化ツールは、これらのテクニックと他のテクニックを組み合わせて使用します。
残念ながら、どちらのアプローチでもJVMが実行するコードを実際に変更する必要があり、多くのユーザーは(当然のことながら)この変換によってアプリケーションに新しいバグが追加されることを恐れています。さらに、メソッドとフィールドの名前を変更すると、リフレクション呼び出しが機能しなくなる可能性があります。実際のクラス名とパッケージ名を変更すると、他のいくつかのJava API(JNDI(Javaネーミングおよびディレクトリインターフェース)、URLプロバイダーなど)が壊れる可能性があります。名前の変更に加えて、クラスのバイトコードオフセットとソース行番号の間の関連付けが変更されると、元の例外スタックトレースの回復が困難になる可能性があります。
次に、元のJavaソースコードを難読化するオプションがあります。しかし、基本的にこれは同様の一連の問題を引き起こします。暗号化し、難読化しませんか?
おそらく上記のことから、「バイトコードを操作する代わりに、コンパイル後にすべてのクラスを暗号化し、JVM内でその場で復号化するとどうなるでしょうか(カスタムクラスローダーで実行できます)。元のバイトコードですが、逆コンパイルまたはリバースエンジニアリングするものは何もありませんよね?」
残念ながら、あなたはこのアイデアを思いついた最初の人であると考えることと、それが実際に機能することを考えることの両方で間違っているでしょう。そして、その理由はあなたの暗号化スキームの強さとは何の関係もありません。