繁体   English   中英

为什么Spring的MessageDigestPasswordEncoder将`{}`放入盐中? 其javadoc中的示例似乎不起作用

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

我正在从Spring Security 4.x升级到5.x。

Spring 4的ReflectionSaltSource使我们可以配置自定义盐。 但这在Spring Security 5中已删除。然后我发现我应该使用MessageDigestPasswordEncoder 它有一个很长的详细的Java文档,但是不幸的是,该文档是一堆单词,没有传达任何结构化的信息(我尝试了多次;如果我一无所知,那会很糟糕)。

无论如何,基于我的有限理解,我认为我应该执行以下操作。

使用4.x的旧系统 myEncodedPasswordmySalt分别传递到编码器。

使用5.x的新系统 -将值为{mySalt}myEncodedPassword一个字段{mySalt}myEncodedPasswordMessageDigestPasswordEncoder

但是,那没有用。 问题在于,当MessageDigestPasswordEncoder看到{mySalt}encodedPassword ,它使用{mySalt} (带有{})作为盐,而不是使用mySalt作为盐。 我糊涂了。

这是一个编码示例。 我使用Groovy来减少噪音。

@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?

输出是

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

我希望找到一种方法为每个用户密码使用自定义和单独的盐支持SHA256。


如果有人感兴趣,我会在GitHub- https://github.com/spring-projects/spring-security/issues/6594上创建票证。 到目前为止没有解决方案。 如果有的话,我会在这里更新。 因此,这仍然是一个悬而未决的问题。

我猜问题出在org.springframework.security.crypto.password.MessageDigestPasswordEncoder类中

通过在private String extractSalt(String prefixEncodedPassword)方法中对其进行调试,他们尝试通过返回prefixEncodedPassword.substring(start, end + 1);来提取盐prefixEncodedPassword.substring(start, end + 1); 其中start是前缀{的索引,而end是后缀的索引} ,并且停止到它匹配的第一个后缀,那么代码中会发生什么?

发生这种情况:

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

我声明我不知道它是否是错误,无论如何在您的情况下,它都足以正确调查和正确修改方法

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);
    }

此方法在org.springframework.security.crypto.password.MessageDigestPasswordEncoder类内部

我希望它有用

安杰洛

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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