2

Javaアプリをコーディングしましたが、オンラインで配布する予定です。各リリースは、私が作成した秘密のシリアルキーでロックされます。

逆コンパイラなどからjarファイルを保護する必要があります。これまでに行ったことは次のとおりです。

  1. ユーザーが自分のシリアルキーをフォームに入力します
  2. シリアルは、phpスクリプトを介して開発サーバーに送信されます
  3. スクリプトは、AES128で暗号化された新しいjarbinファイルを生成します
  4. 私の「ローダー」はjarファイルをバイトとしてダウンロードして復号化します。
  5. mainメソッドを呼び出します。
  6. ユーザーは好きなようにアプリを使用できます
  7. ユーザーがアプリを閉じる
  8. キャッシュがクリアされ、すべてがステップ1以前に戻ります。

手順1から3を実行しましたが、HTTPからバイトを取得し、それらを復号化してmainメソッドを呼び出すカスタムクラスローダーを作成できるかどうかを知る必要があります。ファイルは完全に暗号化されているため(PHPサーバーにbinとして保存されているため)、基本的なクラスローダーを使用できません。手順8について、コンピュータのメモリからコンテンツをアンロードすることはできますか?

4

2 に答える 2

5

はい、可能ですが、無駄でもあります。

クラスローダは、セキュリティ システムの最も弱い点になります。暗号化できないため、逆コンパイルするのは比較的簡単です。

クラスローダーにはバイト配列の形式で復号化されたクラスが必要な場所があるため、攻撃者がしなければならない唯一のことは、このバイト配列をファイルにダンプすることです。

dystroyのコードを参照する:

classBytes = EncryptionUtil.decryptBytes(url, key); 

// In this moment, classBytes contains unencrypted class.
// If an attacker adds:   
//
//   FileOutputStream fos = new FileOutputStream("some.name");
//   fos.write(classBytes);
//   fos.close();
// 
// he will destroy all your security.


return defineClass(name, classBytes, 0, classBytes.length);
于 2012-06-21T11:55:52.167 に答える
0

はい、取得したバイトをクラスローダーに提供できます。私は同様の問題でそれを行います:

public class SecureClassLoader extends URLClassLoader {

    @Override
    protected Class<?> findClass(final String name) throws ClassNotFoundException {
        if (isEncrypted(name)) {
            final String resourceName = name.replace('.', '/') + ".class";
            URL url = findResource(resourceName);
            if (url != null) {
                byte[] classBytes = null;
                try {
                    classBytes = EncryptionUtil.decryptBytes(url, key);
                    return defineClass(name, classBytes, 0, classBytes.length);
                } catch (ClassFormatError e) {
                    log.severe("Bad format for decrypted class " + name);
                    throw new EncryptedClassNotFoundException(name, e);
                } catch (InvalidKeyException e) {
                    throw new EncryptedClassNotFoundException(name, e);
                } catch (IOException e) {
                    throw new EncryptedClassNotFoundException(name, e);
                }
            }
        }

        // default loader
        try {
            return super.findClass(name);
        } catch (ClassNotFoundException e) {
            throw new EncryptedClassNotFoundException(name, e);
        }
    }

    private boolean isEncrypted(String className) {
        /// some things
    }
}

しかし、これはコードを保護するには不十分です。少なくとも、2 人のユーザーに同じバイトを使用しないでください (使用しているようです)。コードを難読化します (私は proguard を使用しています)。これにより、最高のハッカーではなく、通常のハッカーから保護されます。

于 2012-06-21T11:56:14.690 に答える