Saler les données en Spring

Protection supplémentaire pour les informations sensibles

Ce site ne sera plus alimenté de contenu après août 2014. Tous les nouveaux articles seront redigés pour www.waitingforcode.com

Certaines données dans notre système sont plus importantes que les autres. Il s'agit par exemple des mots de passes qu'on devra protéger avec une couche supplémentaire. Cette couche consistera à saler le mot de passe, c'est-à-dire, à le rendre plus difficile à deviner par un utilisateur malveillant. L'article ci-dessous présentera la technique employée dans ce but.

Saller le mot de passe dans Spring

Le sel est utilisé dans les mots de passe pour les rendre plus difficilement identifiables par les utilisateurs malveillants. Le salage consiste à rajouter une chaîne de caractères supplémentaires au mot de passe de l'utilisateur. Au mieux, il faut que ce mot soit le plus personnel possible.

Dans notre cas, le salage sera fait avec la classe SaltCellar, définie dans notre fichier de sécurité :

afficher le code

La seule chose intéressante de ce bout de code est la présence de la map qui contient les relations entre les caractères et les composants du sel. L'implémentation de ce bean se présente de la manière suivante :

public class SaltCellar implements SaltSource {
    final Logger logger = LoggerFactory.getLogger(SaltCellar.class);
    private Map<String, String> saltData;
    @Autowired
    private ShaPasswordEncoder passwordEncoder;
    
    public void setSaltData(Map<String, String> saltData) {
        logger.info("Put new salt data " + saltData);
        this.saltData = saltData;
    }
    
    /**
     * Salt is always constructed on login property.
     * @access public
     * @param UserDetails user Connected user instance.
     * @return Object Salt used in password.
     */
    public Object getSalt(UserDetails user) {
        logger.info("Getting salted password from UserDetails instance " + user);
        return getSaltFromString(user.getUsername());
    }
    
    public String getSaltFromString(String value) {
        if (value == null) return "-";
        StringBuffer salt = new StringBuffer();
        String[] loginParts = value.split("");
        for (int i = 0; i < loginParts.length; i++) {
            logger.info("Looking for " + loginParts[i]);
            if (!loginParts[i].equals("") && saltData.containsKey(loginParts[i].toLowerCase())) {
                salt.append(saltData.get(loginParts[i].toLowerCase()));
            }
        }
        logger.info("Generated salt = " + new String(salt));
        // logger.info("Encoded password = " + passwordEncoder.encodePassword("bartosz", "a"));
        logger.info("Encoded password salt = " + passwordEncoder.encodePassword("bartosz", new String(salt)));
        logger.info("Encoded password salt for admin = " + passwordEncoder.encodePassword("admin", new String(salt)));
        return new String(salt);
    }
}

La classe implémente l'interface org.springframework.security.authentication.dao.SaltSource dont la méthode getSalt() retourne le sel à rajouter dans le mot de passe. Dans notre cas, le sel est basé sur le login de l'utilisateur qui est ensuite traduit en une nouvelle chaîne de caractères. Cette nouvelle chaîne de caractères est composée par les éléments définis dans la map de notre bean.

Bartosz KONIECZNY Sécurité

Une question ? Une remarque ?

*

*

Un conseil Android

Comment accéder au localhost ?

A la place de 127.0.0.1 il faut utiliser 10.0.2.2.