Spring Security(三十三):10.3 Password Encoding
Spring Security’s PasswordEncoder
interface is used to support the use of passwords which are encoded in some way in persistent storage. You should never store passwords in plain text. Always use a one-way password hashing algorithm such as bcrypt which uses a built-in salt value which is different for each stored password. Do not use a plain hash function such as MD5 or SHA, or even a salted version. Bcrypt is deliberately designed to be slow and to hinder offline password cracking, whereas standard hash algorithms are fast and can easily be used to test thousands of passwords in parallel on custom hardware. You might think this doesn’t apply to you since your password database is secure and offline attacks aren’t a risk.
org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder"
org.springframework.security.authentication.encoding
DaoAuthenticationProvider
can be injected with either the new or legacy
PasswordEncoder
types.
如果您使用的是已經具有雜湊密碼的舊系統,那麼您將需要使用與當前演算法匹配的編碼器,至少在您將使用者遷移到更安全的方案之前(通常這將涉及要求使用者設定)一個新密碼,因為雜湊是不可逆轉的)。 Spring Security有一個包含傳統密碼編碼實現的包,即org.springframework.security.authentication.encoding。可以使用新的或舊的PasswordEncoder型別注入DaoAuthenticationProvider。
10.3.1 What is a hash?
Password hashing is not unique to Spring Security but is a common source of confusion for users who are not familiar with the concept. A hash (or digest) algorithm is a one-way function which produces a piece of fixed-length output data (the hash) from some input data, such as a password. As an example, the MD5 hash of the string "password" (in hexadecimal) is
密碼雜湊並非Spring Security獨有,但卻是不熟悉該概念的使用者常見的混淆源。雜湊(或摘要)演算法是單向函式,其從一些輸入資料(例如密碼)產生一段固定長度的輸出資料(雜湊)。例如,字串“password”(十六進位制)的MD5雜湊值是5f4dcc3b5aa765d61d8327deb882cf99
A hash is "one-way" in the sense that it is very difficult (effectively impossible) to obtain the original input given the hash value, or indeed any possible input which would produce that hash value. This property makes hash values very useful for authentication purposes. They can be stored in your user database as an alternative to plaintext passwords and even if the values are compromised they do not immediately reveal a password which can be used to login. Note that this also means you have no way of recovering the password once it is encoded.
在某種意義上,雜湊是“單向的”,即在給定雜湊值的情況下獲得原始輸入是非常困難的(實際上是不可能的),或者實際上任何可能產生該雜湊值的輸入。此屬性使雜湊值對於身份驗證非常有用。它們可以儲存在您的使用者資料庫中,作為明文密碼的替代方法,即使這些值被洩露,它們也不會立即顯示可用於登入的密碼。請注意,這也意味著您無法在編碼後恢復密碼。10.3.2 Adding Salt to a Hash
One potential problem with the use of password hashes that it is relatively easy to get round the one-way property of the hash if a common word is used for the input. People tend to choose similar passwords and huge dictionaries of these from previously hacked sites are available online. For example, if you search for the hash value 5f4dcc3b5aa765d61d8327deb882cf99
using google, you will quickly find the original word "password". In a similar way, an attacker can build a dictionary of hashes from a standard word list and use this to lookup the original password.
The legacy approach to handling salt was to inject a SaltSource
into the DaoAuthenticationProvider
, which would obtain a salt value for a particular user and pass it to the PasswordEncoder
. Using bcrypt means you don’t have worry about the details of salt handling (such as where the value is stored), as it is all done internally. So we’d strongly recommend you use bcrypt unless you already have a system in place which stores the salt separately.
10.3.3 Hashing and Authentication
When an authentication provider (such as Spring Security’s DaoAuthenticationProvider
) needs to check the password in a submitted authentication request against the known value for a user, and the stored password is encoded in some way, then the submitted value must be encoded using exactly the same algorithm. It’s up to you to check that these are compatible as Spring Security has no control over the persistent values. If you add password hashing to your authentication configuration in Spring Security, and your database contains plaintext passwords, then there is no way authentication can succeed. Even if you are aware that your database is using MD5 to encode the passwords, for example, and your application is configured to use Spring Security’s Md5PasswordEncoder
, there are still things that can go wrong.
encode
method on the
PasswordEncoder
.
如果要直接在Java中生成編碼密碼以儲存在使用者資料庫中,則可以在PasswordEncoder上使用encode方法。