Search code examples
grailsspring-security

Issue in encoding password with spring security


I am using grails 2.3.0 and facing the weird issue when encoding the password with spring security:

This is my method to encode password:

String encodePassword(String password) {
    return springSecurityService.encodePassword(password)
}

and using like that

log.debug encodePassword("mkb")
log.debug encodePassword("mkb")
log.debug encodePassword("mkb")

I am encoding the same password several times and each time I am getting the different encoded password.

logs:

$2a$10$h8T4BxgOeozmH/VSPJl7NeTaF2P0iONpSdqDN7dDFFAG.sy8WG/8K
$2a$10$a7qybaiLF/eNrTSwFohjkezNaJTTDdMEinRYKjxDzEt.OoxaIgFOu
$2a$10$nZVhUT0QTmmbtt22CPtM..cLxU252RGBIMkd5aSd2AFXNTNLQ./6u

Solution

  • That's fine. Looks like you're using BCrypt password hash, this algorithm uses random salt each time you encode password (other hashing algorithms use a 'salt source property', like id). This salt is prepended to hash

    So you have:

    • $2a - salt version
    • $10 - rounds
    • $h8T4BxgOeozmH/VSPJl7NeTaF2P0iONpSdqDN7dDFFAG.sy8WG/8K - Base64 for salt+hash, where salt get first 24 characters, and hash takes the rest:
      • h8T4BxgOeozmH/VSPJl7NeTaF - salt
      • 2P0iONpSdqDN7dDFFAG.sy8WG/8K - hash (10 rounds for salt + password)

    See Spring Security's BCrypt sources: https://github.com/spring-projects/spring-security/blob/master/crypto/src/main/java/org/springframework/security/crypto/bcrypt/BCrypt.java

    If you need to check user password manually, you have to use passwordEncoder, like:

    //dependency injection
    def passwordEncoder
    
    //validate
    String enteredPassword = params.password
    User user = ...
    if (!passwordEncoder.isPasswordValid(user.password, enteredPassword, null)) { //validates raw password against hashed
       //... wrong password entered
    }