Issue in encoding password with spring security
Asked Answered
V

2

7

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
Vestiary answered 21/10, 2013 at 15:14 Comment(0)
M
15

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
}
Musicology answered 21/10, 2013 at 15:23 Comment(5)
Why do you want to? Isn't it sufficient that the passwords are hashed and that you can login?Oceanus
I am implementing password reset functionality for which I need to check my current saved password with current password entered by the user.Vestiary
Thanks @Igor and @Burt. passwordEncoder.matches doesn't work in my case(I have injected the passwordEncoder bean), may be I am doing something wrong. passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null) gives me the desired result.Vestiary
Sorry, just figured out that matches is from SS version 3.1. the plugin uses SS 3.0. Btw, passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null) doesn't compare with stored password, maybe you mean passwordEncoder.isPasswordValid(user.password, 'mkb', null)?Musicology
Yes you are right I mean passwordEncoder.isPasswordValid(user.password, 'mkb', null). passwordEncoder.isPasswordValid(encodePassword('mkb'), 'mkb', null) is just for testing. Thanks once again.Vestiary
T
0

Grails spring security describes the process of updating a password at: https://grails-plugins.github.io/grails-spring-security-core/4.0.x/index.html

    User user = User.findByUsername(username)
   if (!passwordEncoder.matches(password, user.password)) {
      flash.message = 'Current password is incorrect'
      render view: 'passwordExpired', model: [username: session['SPRING_SECURITY_LAST_USERNAME']]
      return
   }

   if (passwordEncoder.matches(password_new, user.password)) {
      flash.message = 'Please choose a different password from your current one'
      render view: 'passwordExpired', model: [username: session['SPRING_SECURITY_LAST_USERNAME']]
      return
   }

Where password or new_password are parameters or method arguments

Tolbooth answered 16/8, 2021 at 13:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.