[英]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的舊系統 myEncodedPassword
和mySalt
分別傳遞到編碼器。
使用5.x的新系統 -將值為{mySalt}myEncodedPassword
一個字段{mySalt}myEncodedPassword
給MessageDigestPasswordEncoder
但是,那沒有用。 問題在於,當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.