11 sept. 2016, 11:21

Sommaire

Introduction

Dans ce tutoriel je vais vous montrer comment sécuriser votre mod.

ATTENTION ! Lisez d’abord cette partie avant d’attaquer le tutoriel

La technique ici est de rajouter une signature au jar, mais cette technique n’est pas infaillible ! Si la personne supprime la signature et arrive à modifier la classe qui regarde la signature dans votre mod par n’importe quel moyen vous n’aurez aucun moyen de contrer ça.

Pré-requis

Code

Tout d’abord il va vous falloir créer un fichier où vous allez stocker vos informations sur votre signature, pour ça lancez la console (dans le dossier de votre mod si vous voulez placer le fichier dans le dossier de votre mod) :
keytool -genkey -alias <votre pseudo> -keyalg RSA -keysize 2048

Si vous voulez modifier l’emplacement du keystore rajoutez -keystore <emplacement>
Par défaut le fichier se trouve dans C:/Users/<utilisateur>/.keystore sous windows, et /home/<utilisateur>/.keystore sous Linux

Vous devrez donc répondre à plusieurs questions : la première sera le mot de passe du keystore ensuite vous aurez des questions plus personnelles (conseil : ne mettez pas vos informations personnelles car ces informations se trouveront dans votre jar) comme votre nom et prénom (ou pseudo), ville, pays etc. Ensuite donnez le mot passe de la clé du keystore, par défaut c’est celle du keystore (entrez pour laisser les valeurs par défaut).

Maintenant rendez-vous dans le dossier de gradle général : par défaut le dossier se trouve dans C:/Users/<utilisateur>/.gradle, /home/<utilisateur>/.gradle sous linux et /Users/<utilisateur>/.gradle sous Max. Si vous avez modifié l’emplacement dans gradle rendez-vous dans exécuter et tapez %GRADLE_USER_HOME% ce qui vous amènera directement dans le dossier de gradle.

Vous devriez voir un fichier appelé gradle.properties, si ce n’est pas le cas créez le et remplissez ces informations :

  • keyStore=<lien vers votre keystore créé plus tôt>
  • keyStoreAlias=<votre pseudo>
  • keyStorePass=<mot de passe du keystore>
  • keyStoreKeyPass=<mot de passe de la clé du keystore>

build.gradle :

Rajoutez une tâche signJar (ou un autre nom) :

task signJar(type: SignJar) {
    onlyIf { // On exécute seulement s'il y a un keystore spécifié dans le gradle.properties
        project.hasProperty('keyStore')
    }

    keyStore = project.keyStore // on indique le keystore ainsi que toutes les autres variables
    alias = project.keyStoreAlias
    storePass = project.keyStorePass
    keyPass = project.keyStoreKeyPass
    inputFile = jar.archivePath // On indique le jar d'entrée et de sortie
    outputFile = jar.archivePath
}

assemble.dependsOn signJar // Lorsque l'on compile le jar on le signe

Si vous voulez signer plusieurs jar rajoutez une tâche pour chaque en changeant l’emplacement du jar en n’oubliant pas de les exécuter.

Maintenant vous allez devoir rajouter la signature dans votre mod, donc si vous utilisez l’interface @Mod suivez le premier cas sinon si vous utilisez un plugin fml suivez le deuxième cas.

Classe principale :

Lancez la console et tapez : keytool -list -alias <votre pseudo> -v (rajoutez -keystore <emplacement du keystore> si vous utilisez un emplacement spécifique).
Vous allez donc devoir taper le mot de passe du keystore, puis les informations du keystore s’afficheront, ce qui nous intéresse c’est le SHA1 : rendez-vous dans l’interface @Mod et rajoutez la variable certificateFingerprint de type String avec comme valeur le SHA1 dans la console sans les “:” et en minuscules.

exemple : @Mod(modid = “modid”, certificateFingerprint = “ab57cd89ef”)

Maintenant rajoutez une fonction avec comme paramètre FMLFingerPrintViolationEvent avec l’annotation @EventHandler. Cette fonction sera appelée si le certificat n’est pas valide (en réalité cette fonction ne sera appelée que si vous spécifiez la variable certificateFingerprint mais qu’il n’y pas de signature, dans le cas où le certificat n’est pas correct c’est la JVM qui empêchera la lecture du fichier)

FML Plugin :

Si vous utilisez un plugin fml ça va être différent :

Si vous avez un ModContainer ré-écrivez la fonction getSigningCertificate et renvoyez ceci :

@Override
    public Certificate getSigningCertificate() {
        Certificate[] certificates = getClass().getProtectionDomain().getCodeSource().getCertificates(); // On récupère les certificats
        return certificates != null ? certificates[0] : null; // On renvoie le premier certificat s'il existe
    }

Maintenant dans votre plugin fml rajoutez une classe de setup :

@Override
    public String getSetupClass() {
        return CallHook.class.getName();
    }
public class CallHook implements IFMLCallHook
    {
        @Override
        public Void call() throws Exception {
            if (getClass().getProtectionDomain().getCodeSource().getCertificates() == null) { // On regarde s'il n'y a pas de certificat
                System.out.println("DO NOT USE THIS JAR !"); // On affiche un message
            }
            return null;
        }

        @Override
        public void injectData(Map <string, object="">data) {}
    }

Grâce à ceci un message s’affichera en disant de ne pas utiliser le mod s’il n’y a pas de certificat. Si un fichier a été modifié le fichier sera considéré comme illisible ce qui dans la plupart des cas fera crasher le jeu ou bien votre mod ne sera pas chargé.

En revanche comme je l’ai dit au début si une personne supprime le certificat et modifie les fonctions regardant si le certificat est présent vous n’avez AUCUN moyen fiable de savoir si le jar a été modifié.

Crédits

Rédaction :

  • SCAREX

Correction :

  • Toutoune1008

Creative Commons
Ce tutoriel de SCAREX publié sur Minecraft Forge France est mis à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 4.0 International

retourSommaire des tutoriels