Signature en Java

Java gère les clés et les certificats dans des fichiers protégés appelés keystore. Il existe un keystore par défaut qui contient les certificats de confiance :

$JAVA_HOME/jre/lib/security/cacerts

La commande keytool permet de manipuler (lister et supprimer les clés, en créer et en importer) d’un keystore.

  • Lister les clés du keystore par défaut (mot de passe vide)
    • keytool -list -keystore $JAVA_HOME/jre/lib/security/cacerts

Les personnels et étudiants des universités peuvent obtenir des certificats X.509 officiels ici : https://digicert.com/sso

A l’heure actuelle les certificats proposés ne contiennent pas l’attribut indiquant qu’ils peuvent servir à signer du code mais uniquement des emails. Cela provoque pour le moment un avertissement lors de l’utilisation.

Le certificat obtenu peut être importé dans un keystore :

keytool --import -file ... -keystore ... -alias ...

Les valeurs des paramètres (…) sont à remplacer dans l’ordre par : le chemin vers le fichier contenant le certificat (ex. bruno_emmanuel.crt) le chemin vers le fichier qui contiendra le keystore (ex. ~/.keystore/test.keystore), l’alias qui sera associé au certificat dans le keystore (par exemple votre email certifié).

Une alternative est d’utiliser une certificat auto signé :

keytool -dname "CN=DOE john, OU=dpt-info, O=UTLN, L=La Garde, ST=PACA, C=FR" -storepass password -keypass password -alias johnkey -genkeypair -keyalg EC -keysize 571 -keystore keystore.jks -validity 730

Dans le ~/.m2/settings.xml (donc propre à chaque utilisateur et non commun au projet), il est possible d’indiquer le chemin, l’alias et de mot de passe permettant d’accéder au certificat qui sera utilisé par maven.

<properties>
  <jarsigner.keystore>...</jarsigner.keystore>
  <jarsigner.alias>...</jarsigner.alias>
  <jarsigner.storepass>...</jarsigner.storepass>
</properties>

Ensuite dans le projet on peut indiquer (dans le pom parent) que le plugin de signature doit être utilisé.

<!-- Signature des jar -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jarsigner-plugin</artifactId>
                <version>1.2</version>
                <executions>
                    <execution>
                        <id>sign</id>
                        <goals>
                            <goal>sign</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Puis dans chaque module contenant un ou plusieurs artefact à signer, on indiquer son nom (élément archive).

<plugin>                                                           
 <groupId>org.apache.maven.plugins</groupId>                        
 <artifactId>maven-jarsigner-plugin</artifactId>                    
 <configuration>                                                    
  <archive>${project.build.directory}/${project.build.finalName}.jar</archive>                                                                     
 </configuration>                                                   
</plugin>

Il peut être utile de signer les compilations standards avec un certificat autosigné commun et uniquement certaines avec un certificat de confiance. Pour faire cela, il est assez simple de définir un profil dans le pom parent du projet qui fixe les paramètres d’un keystore par défaut et de définir un profile dans le settings.xml pour indiquer l’autre keystore.

La difficulté principale est lié au partage du keystore commun.

  1. L’utilisation d’un chemin absolu dans le pom.xml casse le partage simple entre utilisateurs et/ou le serveur d’intégration continue.
  2. L’utilisation d’un chemin asbolu dans le settings.xml est très lourde

Une solution assez élégante est de mettre le keystore dans un artefact, d’en faire une dépendance des projets et de l’extraire avant la signature cf. http://maksim.sorokin.dk/it/2010/08/19/signing-jars-on-a-build-server/

—- dataentry page —- type : Howto technologie_tags : Java, X509, keytool, keystore theme_tags ; Signature