91 votes

Comment verrouiller les classes Java compilées pour empêcher leur décompilation ?

Comment verrouiller les classes Java compilées pour empêcher leur décompilation ?

Je sais que ce sujet doit être très bien discuté sur Internet, mais je n'ai pu parvenir à aucune conclusion après les avoir consultés.

De nombreuses personnes proposent des obfuscateurs, mais ils se contentent de renommer les classes, les méthodes et les champs avec des séquences de caractères difficiles à mémoriser, mais qu'en est-il des valeurs constantes sensibles ?

Par exemple, vous avez développé le composant de cryptage et de décryptage basé sur une technique de cryptage par mot de passe. Dans ce cas, n'importe quel utilisateur moyen de Java peut utiliser la technique de cryptage par mot de passe. JAD pour décompiler le fichier de classe et récupérer facilement la valeur du mot de passe (défini comme une constante) ainsi que le nom de l'utilisateur. sel et peut à son tour décrypter les données en écrivant un petit programme indépendant !

Ou bien ces composants sensibles doivent-ils être construits en code natif (par exemple, VC++) et être appelés par l'intermédiaire de la fonction JNI ?

93voto

Roland Tepp Points 2647

Certains des obfuscateurs de bytecode Java les plus avancés vont bien au-delà de la simple manipulation des noms de classe. Zelix KlassMaster par exemple, peut également brouiller le flux de votre code d'une manière qui le rend vraiment difficile à suivre et fonctionne comme un excellent optimiseur de code...

De plus, de nombreux obfuscateurs sont également capables de brouiller vos constantes de chaîne et de supprimer le code inutilisé.

Une autre solution possible (n'excluant pas nécessairement l'obfuscation) est d'utiliser fichiers JAR cryptés et un classloader personnalisé qui effectue le décryptage (de préférence en utilisant une bibliothèque d'exécution native).

La troisième solution (qui offre peut-être la protection la plus solide) consiste à utiliser des compilateurs natifs en avance sur le temps comme CCG ou Excelsior JET par exemple, qui compilent votre code Java directement vers un binaire natif spécifique à la plate-forme.

Dans tous les cas, vous devez vous rappeler que, comme le dit le proverbe estonien, "les verrous sont pour les animaux". Cela signifie que chaque morceau de code est disponible (chargé en mémoire) pendant l'exécution et qu'avec suffisamment de compétences, de détermination et de motivation, les gens peuvent et vont décompiler, décrypter et pirater votre code... Votre travail consiste simplement à rendre le processus aussi inconfortable que possible tout en continuant à faire fonctionner le système...

16voto

Erlend Halvorsen Points 843

Tant qu'ils ont accès à la fois aux données cryptées et au logiciel qui les décrypte, il n'y a pratiquement aucun moyen de rendre ce système totalement sûr. La façon dont ce problème a été résolu auparavant est d'utiliser une sorte de boîte noire externe pour gérer le cryptage/décryptage, comme des dongles, des serveurs d'authentification à distance, etc. Mais même dans ce cas, étant donné que l'utilisateur a un accès complet à son propre système, cela ne fait que rendre les choses difficiles, pas impossibles - à moins que vous puissiez lier votre produit directement à la fonctionnalité stockée dans la "boîte noire", comme, par exemple, les serveurs de jeux en ligne.

12voto

Daren Thomas Points 26812

Avertissement : je ne suis pas un expert en sécurité.

Cela semble être une mauvaise idée : vous laissez quelqu'un crypter des données avec une clé "cachée" que vous lui donnez. Je ne pense pas que cela puisse être sécurisé.

Peut-être que des clés asymétriques pourraient fonctionner :

  • déployer une licence chiffrée avec une clé publique pour la déchiffrer
  • laisser le client créer une nouvelle licence et vous l'envoyer pour le cryptage
  • renvoyer une nouvelle licence au client.

Je ne suis pas sûr, mais je crois que le client peut en fait chiffrer la clé de licence avec la clé publique que vous lui avez donnée. Vous pouvez ensuite la décrypter avec votre clé privée et la ré-encrypter également.

Vous pourriez conserver une paire de clés publiques/privées distincte pour chaque client afin de vous assurer que vous recevez effectivement les produits du bon client. vous sont responsables des clés...

11voto

Daren Thomas Points 26812

Peu importe ce que vous faites, il peut être "décompilé". Heck, vous pouvez juste le désassembler. Ou regarder un vidage de mémoire pour trouver vos constantes. Vous voyez, l'ordinateur a besoin de les connaître, donc votre code aussi.

Que faire à ce sujet ?

Essayez de ne pas envoyer la clé comme une constante codée en dur dans votre code : Gardez-la comme un paramètre par utilisateur. Rendez l'utilisateur responsable de la gestion de cette clé.

9voto

Dan Dyer Points 30082

Jetez un coup d'œil à la JavaWorld article Craquer le cryptage du code d'octet de Java par Vladimir Roubtsov. Il explique pourquoi le cryptage des fichiers de classe est généralement inutile.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X