Introduction

Le hachage de mot de passe est une étape essentielle pour sécuriser les informations sensibles dans votre application. En Java Spring, vous pouvez utiliser la bibliothèque spring-security-core pour hacher les mots de passe. Cette bibliothèque fournit une implémentation de bcrypt, qui est un algorithme de hachage de mot de passe fort.

Installation

Pour commencer, vous devez ajouter la dépendance spring-security-core à votre fichier pom.xml :

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>





BCrypt

BCrypt est une fonction de hachage de mot de passe qui utilise l'algorithme Blowfish pour hacher les mots de passe. Il est conçu pour être lent et difficile à casser, ce qui le rend plus résistant aux attaques par force brute.

 

Pour hacher un mot de passe avec BCrypt, vous devez d'abord installer la bibliothèque BCrypt dans votre application. Ensuite, vous pouvez utiliser les méthodes de hachage de mot de passe asynchrones ou synchrones de BCrypt pour hacher un mot de passe.

 

BCrypt utilise un algorithme de hachage adaptatif pour stocker les mots de passe, ce qui signifie qu'il génère un sel aléatoire lors du codage des mots de passe et stocke ce sel avec le mot de passe crypté. Cela rend chaque hachage unique, même si deux utilisateurs ont le même mot de passe.

 

Pour vérifier si un mot de passe entré par l'utilisateur correspond au mot de passe stocké, vous pouvez utiliser la méthode `bcrypt.compare()`. Cette méthode compare le mot de passe entré par l'utilisateur avec le mot de passe haché stocké pour voir s'ils correspondent.

 

BCrypt est considéré comme un algorithme de hachage sûr et fiable pour protéger les mots de passe des utilisateurs. Il est largement utilisé dans les applications web pour sécuriser les informations d'identification des utilisateurs.

 
 

Blowfish est un algorithme de chiffrement symétrique par blocs conçu par Bruce Schneier en 19931. Il utilise une taille de bloc de 64 bits et une clé de longueur variable pouvant aller de 32 à 448 bits1. Blowfish est basé sur un schéma de Feistel avec 16 tours et utilise des S-Boxes de grande taille qui dépendent de la clé.
L’algorithme Blowfish gère deux ensembles de clés : les 18 entrées du tableau P et les quatre S-Boxes de 256 éléments chacune. Les S-Boxes acceptent un mot de 8 bits en entrée et produisent une sortie de 32 bits. Une entrée du tableau P est utilisée à chaque tour. heureusement qu'il y a une librairie pour le gérer...

 
 

Un système de jeton, en revanche, est un protocole d’authentification dans lequel les utilisateurs vérifient leur identité en échange d’un jeton d’accès unique. Les utilisateurs peuvent ensuite accéder au site Web, à l’application ou à la ressource pendant toute la durée de vie du jeton sans avoir à saisir à nouveau leurs informations d’identification.

 

BCrypt et les systèmes de jeton peuvent être utilisés ensemble pour renforcer la sécurité des informations d’identification des utilisateurs. Par exemple, lorsqu’un utilisateur se connecte à un système en utilisant un mot de passe, ce mot de passe peut être haché avec BCrypt avant d’être stocké dans la base de données. Lorsque l’utilisateur demande un jeton d’accès, le système peut vérifier que le mot de passe entré correspond au mot de passe haché stocké avant d’émettre un jeton d’accès.

 

Pour ajouter un système de jeton à ce code, vous pouvez suivre les étapes suivantes:

 

Configurez Spring Security pour utiliser BCryptPasswordEncoder pour hacher les mots de passe des utilisateurs. Vous pouvez le faire en définissant un bean BCryptPasswordEncoder dans votre classe de configuration Spring Security et en l’injectant dans votre gestionnaire d’authentification.
Implémentez un filtre de jeton pour gérer l’authentification des utilisateurs à l’aide de jetons. Ce filtre doit intercepter les requêtes entrantes, extraire le jeton d’accès de l’en-tête d’autorisation et vérifier si le jeton est valide.
Si le jeton est valide, le filtre doit charger les détails de l’utilisateur associé au jeton et créer un objet Authentication pour représenter l’utilisateur authentifié. Sinon, le filtre doit renvoyer une réponse d’erreur indiquant que l’authentification a échoué.
Vous pouvez également implémenter un point de terminaison pour émettre des jetons d’accès aux utilisateurs. Ce point de terminaison doit accepter les informations d’identification des utilisateurs, les valider à l’aide de BCryptPasswordEncoder, et si elles sont valides, émettre un jeton d’accès unique pour l’utilisateur.

 

Un filtre de jeton en Java est un composant de sécurité qui intercepte les requêtes entrantes et vérifie si elles contiennent un jeton d’accès valide. Si le jeton est valide, le filtre autorise la requête à passer et à accéder à la ressource protégée. Sinon, le filtre renvoie une réponse d’erreur indiquant que l’authentification a échoué.

 

Un filtre de jeton peut être implémenté en utilisant le framework Spring Security en Java. Spring Security fournit des classes de base pour implémenter des filtres personnalisés, ainsi que des mécanismes pour enregistrer ces filtres dans la chaîne de filtres de sécurité.

 

Pour implémenter un filtre de jeton en Java, vous pouvez étendre la classe OncePerRequestFilter fournie par Spring Security et implémenter la méthode doFilterInternal pour vérifier si la requête contient un jeton d’accès valide. Vous pouvez également utiliser des classes utilitaires fournies par Spring Security pour extraire le jeton d’accès de l’en-tête d’autorisation et pour charger les détails de l’utilisateur associé au jeton

l existe de nombreuses ressources en ligne pour vous aider à implémenter un filtre de jeton en Java, comme ce guide qui explique comment configurer Spring Security pour utiliser des filtres personnalisés et ce tutoriel qui montre comment implémenter un filtre de jeton avec Spring Security.


Utilisation de BCryptPasswordEncoder

BCryptPasswordEncoder est une classe fournie par spring-security-core qui utilise l’algorithme bcrypt pour hacher les mots de passe. Voici comment vous pouvez l’utiliser :

  1. Création d’un bean BCryptPasswordEncoder

    Vous devez créer un bean BCryptPasswordEncoder dans votre classe de configuration principale. Vous pouvez le faire en ajoutant la méthode suivante à votre classe principale Main :

    import org.springframework.context.annotation.Bean;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    
    // ...
    
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
  2. Injection de BCryptPasswordEncoder

    Vous pouvez injecter BCryptPasswordEncoder dans n’importe quelle classe où vous en avez besoin en utilisant l’annotation @Autowired. Par exemple, si vous voulez l’utiliser dans un contrôleur, vous pouvez faire comme ceci :

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    
    // ...
    
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    
  3. Hachage d’un mot de passe

    Pour hacher un mot de passe, vous pouvez utiliser la méthode encode de BCryptPasswordEncoder. Par exemple :

    String password = "myPassword";
    String hashedPassword = bCryptPasswordEncoder.encode(password);
    
  4. Vérification d’un mot de passe

    Pour vérifier un mot de passe, vous devez comparer le mot de passe en clair avec la version hachée. Vous pouvez le faire en utilisant la méthode matches de BCryptPasswordEncoder, comme ceci :

    String plainPassword = "myPassword";
    String hashedPassword = // récupérez le mot de passe haché de la base de données
    
    boolean isPasswordMatch = bCryptPasswordEncoder.matches(plainPassword, hashedPassword);
    

Conclusion

Le hachage des mots de passe est une pratique importante pour sécuriser les informations sensibles dans votre application. En utilisant spring-security-core et BCryptPasswordEncoder, vous pouvez facilement hacher les mots de passe en utilisant l’algorithme bcrypt, qui est un algorithme de hachage fort.

 

Ajouter un système de hachage dans votre code

Pour ajouter un système de hachage comme bcrypt dans votre code Spring Java, vous pouvez utiliser la bibliothèque spring-security-core, qui fournit une implémentation de bcrypt. Voici comment vous pouvez l’utiliser :

  1. Ajoutez la dépendance spring-security-core à votre fichier pom.xml :
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-security</artifactId>
		</dependency>

  1. Modifiez votre méthode addNewUser dans UserController pour hacher le mot de passe avant de le sauvegarder :
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

// ...

@Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;

@PostMapping(path="/add")
public @ResponseBody String addNewUser (@RequestParam String name, @RequestParam String email, @RequestParam String password) {
    User n = new User();
    n.setName(name);
    n.setEmail(email);
    n.setPassword(bCryptPasswordEncoder.encode(password)); // Hachage du mot de passe

 Role role = roleRepository.findById(roleId).orElse(null); // Récupération du rôle à partir de la base de données
    if (role != null) {
        n.setRole(role); // Association du rôle à l'utilisateur
    }

    userRepository.save(n);
    return "Saved";
}
  1. Ajoutez un bean BCryptPasswordEncoder à votre classe de configuration principale :
import org.springframework.context.annotation.Bean;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

// ...

@Bean
public BCryptPasswordEncoder bCryptPasswordEncoder() {
    return new BCryptPasswordEncoder();
}
 

Maintenant, chaque fois que vous créez un nouvel utilisateur, le mot de passe sera haché en utilisant bcrypt avant d’être stocké dans la base de données.

Notez que pour vérifier un mot de passe, vous devrez comparer le mot de passe en clair avec la version hachée stockée dans la base de données. Vous pouvez le faire en utilisant la méthode matches de BCryptPasswordEncoder, comme ceci :

boolean isPasswordMatch = bCryptPasswordEncoder.matches(plainPassword, hashedPassword);
 

Où plainPassword est le mot de passe en clair que vous voulez vérifier, et hashedPassword est le mot de passe haché récupéré de la base de données.

 

Correction du problème de connexion avec bcrypt en localhost

 

Ce code définit une classe WebSecurityConfig qui est une classe de configuration Spring pour la sécurité web. La classe est annotée avec @Configuration et @EnableWebSecurity, ce qui indique qu’elle est une classe de configuration et qu’elle active la sécurité web de Spring. La méthode securityFilterChain crée un bean de type SecurityFilterChain en utilisant l’objet HttpSecurity passé en paramètre. La méthode désactive la protection CSRF en appelant la méthode disable sur l’objet csrf obtenu en appelant la méthode csrf sur l’objet http. La méthode peut également contenir d’autres configurations de sécurité. Finalement, la méthode construit et retourne un objet SecurityFilterChain en appelant la méthode build sur l’objet http.

Il existe plusieurs façons d’implémenter la protection CSRF dans une application. L’une des méthodes les plus courantes consiste à utiliser des jetons CSRF (CSRF tokens). Ces jetons sont des valeurs uniques générées aléatoirement côté serveur et envoyées au client. Le client doit ensuite renvoyer le jeton avec chaque requête modifiant l’état du serveur. Le serveur vérifie alors la validité du jeton avant d’exécuter l’action demandée.

La protection CSRF (Cross-Site Request Forgery) est une mesure de sécurité visant à empêcher les attaques CSRF. Une attaque CSRF se produit lorsqu’un site web malveillant, un email, un blog, un message instantané ou un programme provoque l’exécution d’une action non désirée par l’utilisateur sur un site de confiance lorsqu’il est authentifié. Cette attaque fonctionne car les requêtes du navigateur incluent automatiquement tous les cookies, y compris les cookies de session. Par conséquent, si l’utilisateur est authentifié sur le site, celui-ci ne peut pas distinguer les requêtes authentifiées légitimes des requêtes authentifiées forgées.

Il existe plusieurs méthodes pour se protéger contre les attaques CSRF. L’une des méthodes les plus populaires et recommandées est l’utilisation de jetons CSRF (CSRF tokens). Ces jetons sont des valeurs uniques générées par le serveur et envoyées au client, qui doit les renvoyer avec chaque requête modifiant l’état du serveur. Le serveur vérifie alors la validité du jeton avant d’exécuter l’action demandée. D’autres méthodes incluent l’utilisation de cookies SameSite, la vérification de l’origine des requêtes avec des en-têtes standards, et la mise en place de protections basées sur l’interaction utilisateur pour les opérations hautement sensibles.

En ajoutant la déactivation de la protection CSRF  dans une classe WebSecurityConfig.java, le programme devrait fonctionner à nouveau.

package com.example.demo; // Définition du package

import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration // Cette classe est une classe de configuration Spring
@EnableWebSecurity // Cette annotation active la sécurité web de Spring
public class WebSecurityConfig {

    @Bean // Cette méthode crée un bean de type SecurityFilterChain
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.csrf(csrf -> csrf.disable()); // Désactivation de la protection CSRF
        // Autres configurations de sécurité...
        return http.build(); // Construction et retour du SecurityFilterChain
    }
}
Modifié le: mardi 19 septembre 2023, 03:44