Mise en pratique de https

Comment faire en local

  • Il n’est pas nécessaire d’avoir un certificat signé par une autorité de confiance
  • Un certificat autosigné suffit : c’est un certificat “localhost” signé par “localhost”

Générer un certificat

Les étapes :

  • Générer une clé privée
  • Calculer la clé publique à partir de la clé privée
  • Enrober la clé publique dans une demande de certificat
  • Signer la demande de certificat
  • (facultatif) Générer le bon format d’échange

Qui signe ?

  • Une autorité payante
  • Let’s encrypt
  • Nous-même dans le cadre de l’exercice ! Certifcat dit autosigné, ici généré pour localhost, signé par localhost
# On génère une clé privée
openssl genrsa 2048 > server.key
# On génère la clé publique associé à la clé privée, et on prépare la demande de certificat
openssl req -new -key server.key -out server.csr
> Country Name (2 letter code) [AU]:FR
> State or Province Name (full name) [Some-State]:France
> Locality Name (eg, city) []:Paris
> Organization Name (eg, company) [Internet Widgits Pty Ltd]:Insee
> Organizational Unit Name (eg, section) []:CNIP
> Common Name (e.g. server FQDN or YOUR name) []:localhost
> Email Address []:

> Please enter the following 'extra' attributes
> to be sent with your certificate request
> A challenge password []:
> An optional company name []:
# On fait signer la demande par l'AC qui ici est localhost lui-même
openssl x509 -req -days 365 -in server.csr  -signkey server.key  -out server.crt
# Si on veut transformer en keystore
openssl pkcs12 -export -in server.crt -inkey server.key -out server.p12 -passout pass:changeit

Installation sur tomcat

Configuration des ports d’écoute : dans le server.xml :

Ajout d’un connecteur SSL

  • tomcat <=9
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
			maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
			clientAuth="false" sslProtocol="TLS" keystoreFile="${catalina.home}/conf/ssl/server.p12" keystoreType="pkcs12"
			keystorePass="changeit" />
  • tomcat >=10
	<Connector port="8443" protocol="org.apache.coyote.http11.Http11Nio2Protocol"
               maxThreads="20" SSLEnabled="true" scheme="https" secure="true" defaultSSLHostConfigName="test">
        <SSLHostConfig hostName="test" protocols="TLSv1.2" >
            <Certificate
                certificateFile="${catalina.home}/conf/ssl/server.crt"
                certificateKeyFile="${catalina.home}/conf/ssl/server.key"
            />
        </SSLHostConfig>
    </Connector>

Configuration de la redirection du connecteur par défaut

On définie le port de redirection dans le cas ou une redirection https est imposée par l’application

Ce connecteur existe déjà par défaut, il faut uniquement changer le port de redirection si nécessaire

<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>

Rendre le https obligatoire

web.xml (Tomcat)

<security-constraint>
  <display-name>tout-en-https</display-name>
  <web-resource-collection>
    <web-resource-name>tout</web-resource-name>
    <url-pattern>/*</url-pattern>
  </web-resource-collection>
  <user-data-constraint>
    <transport-guarantee>CONFIDENTIAL</transport-guarantee>
  </user-data-constraint>
</security-constraint>

Spring Security

@Configuration
@EnableWebSecurity
public class MySecurityConfiguration  {
  @Bean
  public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
    http.requiresChannel().anyRequest().requiresSecure();
  }
}

TP

  • Générer un keystore pour une configuration https de localhost
  • Mettre en place https sur un serveur local
  • Forcer le https sur l’application

Le truststore en java

  • Par défaut le trustore chargé est celui de la jvm éxécutant l’application (….\mon-jdk\lib\security\cacerts)

  • Le mot de passe par défaut est changeit

  • On peut vouloir un “Insee flavored cacert” : le cacerts disponible dans la distribution java plus la chaine de certification Insee (AC Racine + AC Subordonnée)

  • Au cas où : certificats AC Insee

  • Pour le changer on utilise des paramètres de la JVM :

    • javax.net.ssl.trustStrore
    • javax.net.ssl.trustStorePassword
    • javax.net.ssl.trustStoreType (par défaut jks)
  • On crée un nouveau truststore, en pratique on ajoute nos certificats au truststore par défaut

  • Créer le truststore

keytool  -import -trustcacerts -file server.crt -alias localhost -keystore cacertsperso

Si keytool inconnu : (à ajouter au path pour plus de simplicité)

"path/to/mon-jdk/bin/keytool.exe"
"$JAVA_HOME/bin/keytool.exe"

Crée le truststore si cacertsperso n’existe pas encore, ajoute le certificat aux existants s’il existe déjà

  • Le déclarer au démarrage :
    • Paramètres de démarrage
-Djavax.net.ssl.trustStore="/path/to/cacerts.jks" -Djavax.net.ssl.trustStorePassword=changeit -Djavax.net.ssl.trustStoreType=JKS
-Djavax.net.debug=all (UNIQUEMENT pour debugger en cas de problème, c'est TRES verbeux)
  • Dans le code :
System.setProperty("javax.net.ssl.trustStore", "/path/to/cacerts.jks");
System.setProperty("javax.net.ssl.trustStorePassword", "changeit");
System.setProperty("javax.net.ssl.trustStoreType", "JKS");

TP

  • Créer un truststore incluant le cacert Insee et le certificat généré précédemment
  • Le faire prendre en compte dans l’application