簡體   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