简体   繁体   中英

Why does Spring's MessageDigestPasswordEncoder take `{}` into the salt? The example in its javadoc does not seem to work

I'm upgrading from Spring Security 4.x to 5.x.

The ReflectionSaltSource from Spring 4 lets us configure a custom salt. But that's removed in Spring Security 5. I then found out that I should use MessageDigestPasswordEncoder . It has a long detailed java-doc but unfortunately the doc is a bag of words without conveying any structured information (I tried multiple times; my bad if I was ignorant).

Anyways I thought I should do the following based on my limited understanding.

Old system with 4.x - myEncodedPassword and mySalt are passed separately to the encoder.

New System with 5.x - Pass one field with the value {mySalt}myEncodedPassword to the MessageDigestPasswordEncoder

However, that did not work. The Problem was that when MessageDigestPasswordEncoder sees {mySalt}encodedPassword , it uses {mySalt} (with the {}) as the salt instead of using mySalt as the salt . I'm confused.

Here's a coding example. I used Groovy to reduce noise.

@Grab(group='org.springframework.security', module='spring-security-core', version='5.1.4.RELEASE')
import org.springframework.security.crypto.password.MessageDigestPasswordEncoder

String password = 'myPassword'
String salt_1 = 'mySalt'
String salt_2 = '{mySalt}'
// http://www.lorem-ipsum.co.uk/hasher.php generated below hashes
String encodedPasswordWithSalt_1 = '57bc828628811a10496215e217b7ae9b714c859fc7a8b1c678c9a0cc40aac422'
String encodedPasswordWithSalt_2 = 'a18b53fc58843def1e08e00a718f40d6f8eda0b97ef97824b5078c1fad93c0c5'

MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder('SHA-256')
println "expected=true, actual=" + encoder.matches(password, "{${salt_1}}${encodedPasswordWithSalt_1}") // <--- expected to match but did not
println "expected=false, actual=" + encoder.matches(password, "{${salt_1}}${encodedPasswordWithSalt_2}") // <--- why does this match?

The output is

expected=true, actual=false
expected=false, actual=true

I'm hoping to find a way to support SHA256 with custom and separate salt for each user password.


If anyone's interested, I created a ticket on GitHub - https://github.com/spring-projects/spring-security/issues/6594 . No solution so far. I will update here if there's any. So this is still an unanswered question.

I guess the issue is in the org.springframework.security.crypto.password.MessageDigestPasswordEncoder class

By debugging it in the method private String extractSalt(String prefixEncodedPassword) they try to extract salt by returning prefixEncodedPassword.substring(start, end + 1); where start is the index of the prefix { while end is the index of suffix } and it stops to the first suffix it matches so what happens in your code?

It happens this:

MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder('SHA-256')
println "expected=true, actual=" + encoder.matches(password, "{${salt_1}}${encodedPasswordWithSalt_1}") //It's not matched because the extracted salt will be {mySalt} and not mySalt
println "expected=false, actual=" + encoder.matches(password, "{${salt_1}}${encodedPasswordWithSalt_2}") //It's matched because the extracted salt will be {mySalt} and not mySalt

I state I don't know if it's a bug or not, in any case in your scenario it should be enough to properly investigate and properly modify the method

private String extractSalt(String prefixEncodedPassword) {
        int start = prefixEncodedPassword.indexOf(PREFIX);
        if (start != 0) {
            return "";
        }
        int end = prefixEncodedPassword.indexOf(SUFFIX, start);
        if (end < 0) {
            return "";
        }
        return prefixEncodedPassword.substring(start, end + 1);
    }

This method is inside the org.springframework.security.crypto.password.MessageDigestPasswordEncoder class

I hope it's useful

Angelo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM